Forum: PC-Programmierung VBA (Excel) und Ethernet TCP/IP


von B@S (Gast)


Lesenswert?

Hallo,

wollte mal euch schlauen Köpfe fragen, ob vieleicht jemand weiß wie ich 
in VBA eine Ethernet- Verbindung hinbekomme. Also mein VBA soll ein 
Client werden. Habe bisher nur mit VB.NET programmiert, aber das ist das 
sehr einfach. In VBA bekomme ich das nicht hin. Und mit "WINSOCK.DLL" 
läufts auch nicht, vermutlich liegts an WIN-Vista. Ich will es möglichst 
so hinbekommen, daß es auf jedem Rechner, der Excel hat auch läuft. 
Deswegen will ichs auch in VBA und nicht in VB.Net, weil da benötigt man 
wieder das Framework, was die Sache unflexiebel machen würde. Vileicht 
kann mir jemand helfen.

Gruss,

B@S

von B@S (Gast)


Lesenswert?

Also die winsock der Version W2_32.dll bindet er ohne mosern ein. Aber 
wie gehts dann weiter? Wieso ist Windows in dieser Ecke nur so 
Umständlich?

von Εrnst B. (ernst)


Lesenswert?

> Wieso ist Windows in dieser Ecke nur so Umständlich?

Vielleicht ist es Absicht? Ich fänds nicht soo prickelnd, wenn jedes 
dumme Excel- oder Powerpoint-File sich nen TCP-Socket zum nächsten 
Mailserver aufbauen kann, und sich dann selbst millionenfach 
weiterverschicken kann.

von B@S (Gast)


Lesenswert?

Tolle Antwort, sehr hilfreich.



Also so weit bin ich bis jetzt gekommen:



------------------------------------------------------------------------ 
---
'This is the Winsock API definition file for Visual Basic


'Setup the variable type 'hostent' for the WSAStartup command
Type Hostent
h_name As Long
h_aliases As Long
h_addrtype As String * 2
h_length As String * 2
h_addr_list As Long
End Type
Public Const SZHOSTENT = 16

'Set the Internet address type to a long integer (32-bit)
Type in_addr
s_addr As Long
End Type

'A note to those familiar with the C header file for Winsock
'Visual Basic does not permit a user-defined variable type
'to be used as a return structure. In the case of the
'variable definition below, sin_addr must
'be declared as a long integer rather than the user-defined
'variable type of in_addr.
Type sockaddr_in
sin_family As Integer
sin_port As Integer
sin_addr As Long
sin_zero As String * 8
End Type


Public Const WSADESCRIPTION_LEN = 256
Public Const WSASYS_STATUS_LEN = 128
Public Const WSA_DescriptionSize = WSADESCRIPTION_LEN + 1
Public Const WSA_SysStatusSize = WSASYS_STATUS_LEN + 1

'Setup the structure for the information returned from
'the WSAStartup() function.
Type WSAData
wVersion As Integer
wHighVersion As Integer
szDescription As String * WSA_DescriptionSize
szSystemStatus As String * WSA_SysStatusSize
iMaxSockets As Integer
iMaxUdpDg As Integer
lpVendorInfo As String * 200
End Type

'Define socket return codes
Public Const INVALID_SOCKET = &HFFFF
Public Const SOCKET_ERROR = -1

'Define socket types
Public Const SOCK_STREAM = 1 'Stream socket
Public Const SOCK_DGRAM = 2 'Datagram socket

Public Const SOCK_RAW = 3 'Raw data socket
Public Const SOCK_RDM = 4 'Reliable Delivery socket
Public Const SOCK_SEQPACKET = 5 'Sequenced Packet socket

'Define address families
Public Const AF_UNSPEC = 0 'unspecified
Public Const AF_UNIX = 1 'local to host (pipes, portals)
Public Const AF_INET = 2 'internetwork: UDP, TCP, etc.
Public Const AF_IMPLINK = 3 'arpanet imp addresses
Public Const AF_PUP = 4 'pup protocols: e.g. BSP
Public Const AF_CHAOS = 5 'mit CHAOS protocols
Public Const AF_NS = 6 'XEROX NS protocols
Public Const AF_ISO = 7 'ISO protocols
Public Const AF_OSI = AF_ISO 'OSI is ISO
Public Const AF_ECMA = 8 'european computer manufacturers
Public Const AF_DATAKIT = 9 'datakit protocols
Public Const AF_CCITT = 10 'CCITT protocols, X.25 etc
Public Const AF_SNA = 11 'IBM SNA
Public Const AF_DECnet = 12 'DECnet
Public Const AF_DLI = 13 'Direct data link interface
Public Const AF_LAT = 14 'LAT
Public Const AF_HYLINK = 15 'NSC Hyperchannel
Public Const AF_APPLETALK = 16 'AppleTalk
Public Const AF_NETBIOS = 17 'NetBios-style addresses
Public Const AF_MAX = 18 'Maximum # of address families

'Setup sockaddr data type to store Internet addresses
Type sockaddr
sa_family As Integer
sa_data As String * 14
End Type
Public Const SADDRLEN = 16

'Declare Socket functions

Public Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) 
As Long
Public Declare Function Connect Lib "wsock32.dll" Alias "connect" (ByVal 
s As Long, addr As sockaddr_in, ByVal namelen As Long) As Long
Public Declare Function htons Lib "wsock32.dll" (ByVal hostshort As 
Long) As Integer
Public Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) 
As Long
Public Declare Function recv Lib "wsock32.dll" (ByVal s As Long, ByVal 
buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
Public Declare Function recvB Lib "wsock32.dll" Alias "recv" (ByVal s As 
Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
Public Declare Function Send Lib "wsock32.dll" Alias "send" (ByVal s As 
Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
Public Declare Function socket Lib "wsock32.dll" (ByVal af As Long, 
ByVal socktype As Long, ByVal protocol As Long) As Long
Public Declare Function WSAStartup Lib "wsock32.dll" (ByVal 
wVersionRequired As Long, lpWSAData As WSAData) As Long
Public Declare Function WSACleanup Lib "wsock32.dll" () As Long
Public Declare Function WSAUnhookBlockingHook Lib "wsock32.dll" () As 
Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" 
(hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)



Public Function ConnectServer(ByVal Hostname As String, ByVal PortNumber 
As Integer) As Integer

Dim StartUpInfo As WSAData
'Version 1.1 (1*256 + 1) = 257
'version 2.0 (2*256 + 0) = 512
'Get WinSock version
'Initialize Winsock DLL
x = WSAStartup(257, StartUpInfo)

Dim I_SocketAddress As sockaddr_in
Dim ipAddress As Long
ipAddress = inet_addr(Hostname) '...........(1)
'Create a new socket
socketId = socket(AF_INET, SOCK_STREAM, 0) '
If socketId = SOCKET_ERROR Then '
MsgBox ("ERROR: socket = " + Str$(socketId)) '...........(2)
OpenSocket = COMMAND_ERROR '
GoTo end1
End If '
'Open a connection to a server
I_SocketAddress.sin_family = AF_INET '
I_SocketAddress.sin_port = htons(PortNumber) '...........(3)
I_SocketAddress.sin_addr = ipAddress '
I_SocketAddress.sin_zero = String$(8, 0) '
x = Connect(socketId, I_SocketAddress, Len(I_SocketAddress)) '
If socketId = SOCKET_ERROR Then '
        MsgBox ("ERROR: connect = " + Str$(x)) '..(4)
        OpenSocket = COMMAND_ERROR '
    Else
        OpenSocket = socketId
End If
end1:
End Function


Public Function RecData(dataBuf As String, ByVal maxLength As Integer) 
As Integer
Dim c As String * 1
Dim length As Integer
dataBuf = ""
While length < maxLength
DoEvents
Count = recv(socketId, c, 1, 0) '
If Count < 1 Then '
RecvAscii = RECV_ERROR '............(1)
dataBuf = Chr$(0) '
GoTo EndRec
End If '
If c = Chr$(10) Then '
dataBuf = dataBuf + Chr$(0) '............(2)
RecvAscii = NO_ERROR '
GoTo EndRec
End If '
length = length + Count '............(3)
dataBuf = dataBuf + c '
Wend
RecvAscii = RECV_ERROR
EndRec:
End Function

Public Sub Disconnect()
x = closesocket(socketId)
If x = SOCKET_ERROR Then MsgBox ("ERROR: closesocket = " + Str$(x))

'Shutdown Winsock DLL
x = WSACleanup()
End Sub

Public Function Sendcommand(ByVal command As String) As Integer
Dim strSend As String
strSend = command + vbCrLf
Count = Send(socketId, ByVal strSend, Len(strSend), 0)
If Count = SOCKET_ERROR Then
        MsgBox ("ERROR: send = " + Str$(Count))
        Sendcommand = COMMAND_ERROR
    Else
        Sendcommand = NO_ERROR
End If
End Function

Public Sub autoscale()
'
' auto scaling
'
Call StartIt
Call get_hostname
x = OpenSocket(Hostname$, ScpiPort)
x = Sendcommand(":DISP:WIND1:TRAC1:Y:AUTO")
Call CloseConnection
Call EndIt
End Sub
------------------------------------------------------------------------ 
---


...und aufgerufen wirds so:


------------------------------------------------------------------------ 
---
Call TCP_Client.ConnectServer("192.168.178.100", 10)
Call TCP_Client.Sendcommand("Hallo")
Call TCP_Client.Disconnect
------------------------------------------------------------------------ 
---
Aber es Kommt kein Hallo beim server an, stattdessen kommt bei diesem 
VBA immer "Error -1".

Weiß jemand woran es liegt?

von Chris (Gast)


Lesenswert?

das ist ganz einfach,

idsocket wurde nicht deklariert und hat aufgrund dessen keinen Wert in 
der Prozedur Sendcommand.

einmal global deklarieren und schon flupp´s... *:-)*

von der mechatroniker (Gast)


Lesenswert?

> Vielleicht ist es Absicht? Ich fänds nicht soo prickelnd, wenn jedes
> dumme Excel- oder Powerpoint-File sich nen TCP-Socket zum nächsten
> Mailserver aufbauen kann, und sich dann selbst millionenfach
> weiterverschicken kann.

Du wirst es nicht so prickelnd finden, aber:

Ein Excel- oder Powerpoint-File darf alles, was auch der Benutzer darf, 
der das Excel oder Powerpoint gestartet hat.

von M. K. (sylaina)


Lesenswert?

Japp, und tatsächlich gibt es auch den ein und anderen Virus, der sich 
in einem PP-File/Excel-File versteckt. Ist nicht schön aber immerhin 
selten.

von Chris (Gast)


Lesenswert?

warum öffnet man auch unbekannte Exceldokumente mit aktiven Makros ?

das grenzt schon an wahnsinn.... Gg

von Sven P. (Gast)


Lesenswert?

Chris schrieb:
> warum öffnet man auch unbekannte Exceldokumente mit aktiven Makros ?
>
> das grenzt schon an wahnsinn.... *Gg*

Weil die meisten Klickibunti-Leute zu dumm sind, es abzustellen oder das 
Risiko zu begreifen.

Spaß beiseite, es funktioniert in VBA vermutlich nicht anders, als 
dazumal in Visual Basic. Und dazu gibt es, abgesehen von tausenden 
Tutorials, auch etliche fertige Klassen.

www.gidf.de

von Christopher H. (Firma: Nector Prime Accounting Soluti) (nector)


Lesenswert?

I would like to find out whether someone managed to have the above VBA 
winsock code work. I keep on getting error send = -1

Here is how Im trying to use it

Public Function ConnectServer(ByVal Hostname As String, ByVal PortNumber 
As Integer) As Integer


Example: Connect("192.168.2.208",8080)

Sending data:

Public Function Sendcommand(ByVal command As String) As Integer

Example : Sendcommand(strData)


Receiving data:
Public Function RecData(dataBuf As String, ByVal maxLength As Integer) 
As Integer

RecData(strdata,Len(strdata)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.