VBA和C#之间的远程集成(使用JSON) [英] Remote integration between VBA and C# (using JSON)

查看:213
本文介绍了VBA和C#之间的远程集成(使用JSON)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一个简单的方法来发送一个字符串(在我的例子中是JSON)从VBA数据提供者到C#服务器。

我的服务器已经在服务器和客户端之间进行了高级别的通信。在我的情况下,我使用CORBA IIOP.NET,但我可以轻松地将其更改为WCF。

My Server already has a high level communication between server and client. In my case I use CORBA IIOP.NET, but I can easily change it to WCF.

我的问题是:如何发送一个字符串到我的C#服务器?

从我的C#服务器我得到代码从代码项目(未测试)

From my C# server I got the code from Code Project (not tested)

public void Server()
{
    //start server
    TcpListener tcpServerListener = new TcpListener(6666);
    tcpServerListener.Start(); 

    //block tcplistener to accept incoming connection
    Socket serverSocket = tcpServerListener.AcceptSocket();

    //open network stream on accepted socket
    NetworkStream serverSockStream = new NetworkStream(serverSocket);
    StreamReader serverStreamReader = new StreamReader(serverSockStream);

    Console.writeLine(serverStreamReader.ReadeLine());
}

我很难通过VBA发送字符串。有人可以帮我吗

I'm having dificult to send the string via VBA. Can anyone help me with that.

PS:在C#中解析JSON我正在使用 JSON .NET 和VBA我使用 VB JSON

PS: To parse JSON in C# I'm using JSON.NET and VBA I'm using VB JSON

推荐答案

现在我看到,我们不能要求良好的做法和理念来帮助VBA ,Excel-VBA标签。所以我做了我的研究,做出了我的选择。让我知道有人有更好的理想做这个远程集成。

Now I see that we can't ask for good practice and ideias to help in VBA, Excel-VBA tags. So I did my research and made my choices. Let me know if someone has a better ideia to do this remote integration.


  1. 首先我选择了JSON,因为我认为这是一个很好的发送方式包不用CORBA。
    所以我发现一个JSON用于 C#实现 VBA实现

  2. 然后我没有没有找到任何协议比TCP好使用。

我的示例有三个测试。一个服务器(C#)和两个可以在下面看到的客户端(C#和VBA)。

My example has three tests. One server (C#) and two clients (C# and VBA) that can be seen bellow.

我使用商店和公司的理念来为良好的继承。这是我的课程:

I use the ideia of Store and Company just to exemplify JSON for .NET works well with inheritance. Here is my classes:

public class Company {
    public string Name { get; set; }
}

public class Store : Company {
    public string Country { get; set; }
    public Dictionary<String, Double> Salaries { get; set; }
}

我的C#客户端只需创建两个 code>序列化并使用 TcpClient 发送到服务器。

My C# client just create two Stores serialize and send it to Server using TcpClient.

代码:

static void Main(string[] args) {

  Store storeUSA = new Store {
    Country = "USA",
    Name = "Amazon.com",
    Salaries = new Dictionary<string, double>{
      {"Jones", 100000},
      {"Deborah",200000}
    }
  };

  Store storeBR = new Store {
    Country = "Brazil",
    Name = "Amazon.com",
    Salaries = new Dictionary<string, double>{
      {"Ricardo", 500000},
      {"Math", 800000}
    }
  };

  TcpClient tcpClient = new TcpClient("192.168.1.63", 6666);
  Console.WriteLine("Connected to Server");

  using (NetworkStream clientSockStream = tcpClient.GetStream()) {
    using (StreamWriter sw = new StreamWriter(clientSockStream)) {

      string output = JsonConvert.SerializeObject(storeUSA, Formatting.None);
      sw.WriteLine(output);
      sw.Flush();

      System.Threading.Thread.Sleep(2000);

      output = JsonConvert.SerializeObject(storeBR, Formatting.None);
      sw.WriteLine(output);
      sw.Flush();

      Console.WriteLine("Closing");
    }
  }

  Console.WriteLine("Done");
  Console.ReadLine();
}

我的VBA客户端略有不同。但是这是一样的想法

My VBA client is a slightly different. But it's the same ideia

代码:

Sub main()
  Dim tcp As New TCPClient
  Dim ok As Boolean

  ok = tcp.Connect("192.168.1.63", 6666)
  If Not ok Then
      Debug.Print "Error Connecting"
      Exit Sub
  End If

  tcp.Send "{""Country"":""France"",""Salaries"":{""Peyton Manning"":800.0,""Blaine Gabbert"":200000.0},""Name"":""Amazon.net""}"
  tcp.CloseConnection

End Sub

最后我的服务器真的很简单。它只是听一个端口,当一个消息来反序列化JSON:

Finally my server that is really simple. It just listen a port and when a message come it deserialize JSON:

static void Main(string[] args){
        IPAddress ip = IPAddress.Parse("192.168.1.63");
        TcpListener tcp = new TcpListener(ip, 6666);

        tcp.Start();
        Console.WriteLine("[DEBUG] End point is: " + tcp.LocalEndpoint);

        Stopwatch time = new Stopwatch();
        time.Start();

        while (time.Elapsed < TimeSpan.FromSeconds(10)){
            TcpClient client = tcp.AcceptTcpClient();

            Console.WriteLine("Receiving message ... ");
            using (NetworkStream networkStream = client.GetStream()){
                using (StreamReader streamReader = new StreamReader(networkStream)){

                    while (!streamReader.EndOfStream){
                        var json = streamReader.ReadLine();
                        Console.WriteLine("JSON:" + json);
                        Store store = JsonConvert.DeserializeObject<Store>(json);
                        Console.WriteLine("Data:");
                        Console.WriteLine(store.ToString());
                    }
                }
            }
            client.Close();
            Console.WriteLine("... Message received");
        }
        tcp.Stop();
        time.Stop();
        Console.WriteLine("Server no longer working");
        Console.ReadKey();
    }

    public class Company{
        public string Name { get; set; }
    }

    public class Store : Company{
        public string Country { get; set; }
        public Dictionary<String, Double> Salaries { get; set; }

        public override string ToString()
        {
            StringBuilder str = new StringBuilder();
            str.Append(String.Format("Name= {0}; Country={1};\n Salaries:\n", Name, Country));
            if (Salaries != null)
            {
                foreach (var salary in Salaries)
                {
                    str.Append(String.Format("  '{0}' = {1}\n", salary.Key, salary.Value));
                }
            }
            return str.ToString();
        }
    }

请注意,我使用 TcpClient 为VBA。关于我们:

Note that I use TcpClient for VBA. Thanks rory - code bellow:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Const sckClosed = 0            ' Default. Closed
Const sckOpen = 1              ' Open
Const sckListening = 2         ' Listening
Const sckConnectionPending = 3 ' Connection pending
Const sckResolvingHost = 4     ' Resolving host
Const sckHostResolved = 5      ' Host resolved
Const sckConnecting = 6        ' Connecting
Const sckConnected = 7         ' Connected
Const sckClosing = 8           ' Peer is closing the connection
Const sckError = 9             ' Error

Const TIMEOUT_MAX As Integer = 10

Private host As String

Private port As String

Private socket As winsock

Function Connect(ByVal fhost As String, ByVal fport As Integer) As Boolean
    Dim secs As Integer


    host = fhost
    port = fport

    Debug.Print Now & " - Client Started"
    Connect = False

    'Create WinSock
    On Error Resume Next
    Set socket = CreateObject("MSWINSOCK.Winsock")
    If Err.Number <> 0 Then
        MsgBox "You need to add MsWinSock reference:" & vbCrLf & "Tools -> References -> Browse -> %SYSEM%\MSWINSCK.OCX"
        Debug.Print Now & " - Winsock Object Error."
        Exit Function
    End If
    On Error GoTo 0

    'Connect
    socket.RemoteHost = host
    socket.RemotePort = port
    socket.Connect

    'Wait for connected state (or TIMEOUT_MAX)
    While socket.State <> sckConnected And secs < TIMEOUT_MAX
        DoEvents
        secs = secs + 1
        Debug.Print Now & " - Waitting for server [" & secs & "/" & TIMEOUT_MAX; "]."
        Sleep 1000
    Wend

    If secs >= TIMEOUT_MAX Then
        Debug.Print Now & " - Client Timed Out"
        CloseConnection
    End If

    Connect = True
End Function

Sub Send(ByVal str As String)
    If socket Is Nothing Then
        Call Err.Raise(3222, "TCPClient::Send", "Socket not Initialized")
    End If

    If socket.State <> sckConnected Then
        Call Err.Raise(3222, "TCPClient::Send", "Not connected")
    End If

    socket.SendData str
    DoEvents
End Sub

Sub CloseConnection()
    If socket.State <> sckClosed Then
        socket.Close
    End If

    Set socket = Nothing
    Debug.Print Now & " - Client Closed."
End Sub


' WINSOCK DATA ARRIVES
Sub winsock_dataArrival(bytesTotal)
    Dim strData
    winsock.GetData strData, vbString
    RecieveData = strData
    WriteData Now & " - Client Recieved: " & RecieveData
    winsock.SendData "Test"
    Wscript.Sleep 1000
    WriteData Now & " - Client Sent Data"
    Call ClientClose
End Sub

' WINSOCK ERROR
Sub winsock_Error(Number, Description, SCode, Source, HelpFile, HelpContext, CancelDisplay)
    MsgBox "Cient Error: " & Number & vbCrLf & Description
    WriteData Now & " - Cient Error: " & Number & ". " & Description
    Call ClientClose
End Sub

我希望它可以用于有人。

I hope that it can be usefull for someone.

这篇关于VBA和C#之间的远程集成(使用JSON)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆