Socket connection using Excel VBA - excel

I have a VB.NET application that successfully sends a string to the specified IP address and port.
Public Sub BroadcastData(ByVal toSend As String, ByVal PortToSendTo As Long)
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim sendBUF As Byte() = Encoding.ASCII.GetBytes(toSend)
Dim ep As New IPEndPoint(MainForm.IPToBroadcastTo, PortToSendTo)
s.SendTo(sendBUF, ep)
System.Diagnostics.Debug.WriteLine(s.SendTo(sendBUF, ep))
End Sub
The IPToBroadcstTo is the IPaddress of a remote computer on the local network.
On this remote computer I can receive this string and do what I want with it using VB.NET.
I would to receive the string in Excel and write it to a cell.

The code you posted is VB.NET. Excel uses VBA which although it shares some common syntax is a completely different language with a reduced set of libraries.
For example there is no Socket or IPEndPoint class in VBA.
So in short the answer is that you can't use that code to open a socket in Excel.
Have a look at the Winsock control or
Maybe you could write a .NET assembly and expose it through COM interop to allow this to be used in Excel.

Related

VB6 - Sending data to Telnet

I've been looking around for some code examples for sending data from a server application in VB6 to Telnet. From what I've seen (Baring in mind these code examples are 15-20 years old), you can only send raw strings?
I'm just playing around with some source code I made, where I have a custom stand-alone client, so I'm sending byte arrays back and forth to handle strings and values. I'm worried that only being able to send raw strings will massively reduce network performance between the server and client.
Are there any other examples?
Currently I send messages like this:
Public Sub SendMsg(ByVal Index As Long, ByVal Msg As String)
Dim Buffer As clsBuffer
Set Buffer = New clsBuffer
Buffer.PreAllocate Len(Msg) + 4
Buffer.WriteInteger SSendMsg
Buffer.WriteString Msg
Call SendDataTo(Index, Buffer.ToArray)
DoEvents
End Sub
The code there is what I currently have to send data to a custom client, not Telnet. My question is, is it possible to send that type of data to Telnet?

HypRetrieve not retrieving correct status code

Background
I have two databases that I need to connect to. One is in Hyperion and the other one is in ESS. I have imported the smartview.bas as stated by the documentation and I am attempting to use the functions within it. I have dummy sheets (SavedLogHyperion and SavedLogESS) for each enviroment to make sure the users logs in before running all the code. I want to retrieve the proper error code if the user closes the window without logging or other things that may prevent the successful login.
Problem
The HypRetrieve only acknowledge for the first result: if the user was able to log to Hyperion environment, but if ESS login window is cancelled or provided with non-valid credentials and then closed, it detects the code as 0 ("Ok"), thus detecting a successful login for the second environment when it was not.
Code
I wrote a function to retrieve the number, I thought that it could be a time thing and that is why I made it (so for the main code could resolve on time), but it seems like it is not.
Function Return_NumCodeSVHypRetrieve(VarTxtSheetToLogin As Variant) As Long
Dim NumCodeHypRetrieve As Long
NumCodeHypRetrieve = HypRetrieve(VarTxtSheetToLogin)
Return_NumCodeSVHypRetrieve = NumCodeHypRetrieve
End Function
This function is called in my main sub
Sub Main()
Dim NumCodeConnectionSheet1 As Long
Dim NumCodeConnectionSheet2 As Long
NumCodeConnectionSheet1 = Return_NumCodeSVHypRetrieve("SavedLogHyperion")
NumCodeConnectionSheet2 = Return_NumCodeSVHypRetrieve("SavedLogESS") 'If I log in "SavedLogHyperion", this variable becomes 0 too, or any other error code that variable had
End Sub
Question
How can I make the correct code according to the sheet attempted to log be correctly saved? I am clueless on what may be the approach
Solution:
The problem seems to be on how the function works; I noticed that when the function is applied, it activates the sheet, which lead me to believe that there was a problem on timing events, I came with the following solution, which has been basically to provide the scenario that I saw the function is expecting to, also I noticed that if I set the NumCode to retrieve as long as the direct result, it does not behave as expected, my approach was to declare it a variant and then cast it to a long instead.
Function Return_NumCodeSVHypRetrieve(VarTxtSheetToLogin As Variant) As Long
Dim VarNumCode As Variant
'It seems the function relies on the sheet being activated and if the Retrives does it, it takes miliseconds to do, which are not sync with excel life cycle, thus causing missreadings
Sheets(VarTxtSheetToLogin).Visible = True: Sheets(VarTxtSheetToLogin).Select: DoEvents
VarNumCode = HypRetrieve(VarTxtSheetToLogin)
Sheets(VarTxtSheetToLogin).Visible = False
Return_NumCodeSVHypRetrieve = CLng(VarNumCode)
End Function

Force a COM server to remain open

I have a COM automation server hosted by a VB6 exe.
The COM API is used from Excel VBA:
Dim o as MyCOMAPI.MyCOMType
Set o = new MyCOMAPI.MyCOMType
o.DoSomething
When I create objects in VBA the exe is started along with COM automation and VBA can use the API.
But the exe is closed quickly and "randomly" by Excel, I guess when Excel decides it doesn't need the COM API anymore.
This behaviour is causing random errors.
The simple solution is to start the exe before running the VBA code ; in this case all is working fine as the exe won't stop running until closed by the user.
Have you some information/documentation about the way Excel VBA manages calls to hosted APIs?
Is there a way to avoid this behaviour and have the exe kept open until the VBA code decides to stop it?
This would be the default behavior for a COM automation server when the last object is dereferenced, meaning that the variable that points to the server is set to nothing.
Now, if your code looks something like this today:
Sub MyFunction()
...
Dim o as MyCOMAPI.MyCOMType
Set o = new MyCOMAPI.MyCOMType
o.DoSomething
End Sub
Then, the server life is connected to the life of the o variable. That variable gets set to nothing when the function is finished, and then the server will be shut down (unless there are other variables keeping it alive).
To make sure that your COM server is kept alive for a longer time, simply define the variable as a Public variable as in the sample below.
This sample will start and show Excel and keep it open until the ShutdownExcel function is called.
Public o As Excel.Application
Sub MakeSureExcelIsRunning()
If o Is Nothing Then
Set o = New Excel.Application
o.Visible = True
End If
End Sub
Sub ShutdownExcel()
Set o = Nothing
End Sub
From COM docs.
**Component Automation**
Shutting Down Objects
ActiveX objects must shut down in the following way:
If the object's application is visible, the object should shut down only in response to an explicit user command (for example, clicking Exit on the File menu) or the equivalent command from an ActiveX client.
If the object's application is not visible, the object should shut down only when the last external reference is gone.
If the object's application is visible and is controlled by an ActiveX client, it should become invisible when the user shuts it down (for example, clicking Exit on the File menu). This behavior allows the controller to continue to control the object. The controller should shut down only when the last external reference to the object has disappeared.
© Microsoft Corporation. All rights reserved.
When you write an COM server exe the first thing you do it take a reference to yourself when starting as a normal exe else the exe shuts down as soon as initialisation is over.

winsock asynchronous receive in Excel

currently wsock.dll is used in Excel 2007 to connect to a TCP server. It is fine that I can send something out. However, regarding receiving, is there any way to make it event driven as I don't know when there is a msg sending to the Excel? And recv call will be blocked until something is arrived.
If you can get your hands on the Winsock ActiveX control then you can used an event-based programming model. I've excerpted this example for Access:
Private Sub axWinsockServer_DataArrival(ByVal bytesTotal As Long)
Dim strClientMsg As String
' The DataArrival event fires on the server when the client sends
' information. Get the data and display it in a text box.
wsServer.GetData strClientMsg, vbString
Me!Text1.Value = strClientMsg
End Sub
Although consider why, exactly, you need a spreadsheet to do network communication.

HTTPS POST request using VBA for Excel

I use "WinHttp.WinHttpRequest.5.1" to send HTTP POST requests from VBA in Excel.
But I could not manage to do it for HTTPS, as I received an SSL certificate error.
What VBA code would you use to negotiate an SSL connection to a website from VBA in Excel ?
The WinHttpRequest object has a SetClientCertificate method. Try this code example taken from the MSDN (I tried to adapt it for VBA):
' Instantiate a WinHttpRequest object. '
Dim HttpReq as new ActiveXObject("WinHttp.WinHttpRequest.5.1")
' Open an HTTP connection. '
HttpReq.Open("GET", "https://www.test.com/", false)
' Select a client certificate. '
HttpReq.SetClientCertificate("LOCAL_MACHINE\Personal\My Certificate")
' Send the HTTP Request. '
HttpReq.Send()
While I have not used the COM component (WinHttpRequest), it seems you need a call to SetClientCertificate prior to calling send, as per the link.
Does that help?
I have the same situation (send a http request from a VBA in Excel); I created three objects:
Set HttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
-- for the http request class, and
Set fsobj = CreateObject("Scripting.FileSystemObject")
Set txtobj = fso.OpenTextFile("C:\PKCERT.PEM")
-- to get into a variable the certificate contents, to pass it to HttpReq.SetClientCertificate,
certificate_data = txtobj.ReadAll
HttpReq.SetClientCertificate (certificate_content)
So I can send the request including its public key certificate, as usual,
HttpReq.Send
P.S. I found a script at http://www.808.dk/?code-simplewinhttprequest -- it worked fine in my case, hope in yours too.

Resources