您阅读标题并呻吟。没关系。我也是。但我们会按照我们的要求做,对吧?我需要构建一个服务,可以从Excel(2003,但我假设任何版本的Excel应该支持此功能)通过一个名字对象访问。目前我所要做的只是将电子表格发布数据发送到从远程计算机上的Windows服务运行的WCF服务。因为这些数据需要通过比VBA更复杂的东西来检索,所以我决定建立一个数据合同。这里是我的代码(目前这只是一个概念验证,但它与完成时需要看的密切相关)。使用包含Excel中的DataContract的wcf服务VBA
这里的WCF相关的东西:
Imports System.ServiceModel
Imports System.Runtime.Serialization
<ServiceContract()>
Public Interface IWCF
<OperationContract()>
Sub PutData(ByVal what As String)
<OperationContract()>
Function GetWhats() As TheWhats()
End Interface
<DataContract()>
Public Class TheWhats
<DataMember()> Public Property Timestamp As DateTime
<DataMember()> Public Property TheWhat As String
End Class
Public Class WCF
Implements IWCF
Shared Whats As New List(Of TheWhats)
Public Sub PutData(ByVal what As String) Implements IWCF.PutData
Whats.Add(New TheWhats With {.Timestamp = Now, .TheWhat = what})
End Sub
Public Function GetWhats() As TheWhats() Implements IWCF.GetWhats
Return Whats.ToArray
End Function
End Class
我的app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true"></compilation>
</system.web>
<system.serviceModel>
<services>
<service name="DataCollectionService.WCF">
<endpoint address=""
binding="netTcpBinding"
contract="DataCollectionService.IWCF" />
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9100/DataCollectionService/ "/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
而我的VBA类来处理发布的东西:
Private Const pConxString As String = _
"service:mexAddress=""net.tcp://localhost:7891/Test/WcfService1/Service1/mex"", " & _
"address=""net.tcp://localhost:7891/Test/WcfService1/Service1/"", " & _
"binding=""NetTcpBinding_IService1"", bindingNamespace = ""http://tempuri.org/"", " & _
"contract=""IService1"", contractNamespace=""http://tempuri.org/"""
Public ServiceObject As Object
Private Sub Class_Initialize()
Set ServiceObject = GetObject(pConxString)
End Sub
Public Sub PutData(ByVal what As String)
ServiceObject.PutData what
End Sub
Private Sub Class_Terminate()
Set ServiceObject = Nothing
End Sub
如果我包括DataContract
属性和返回数据合同对象的函数,我的vba代码在失败方法如下:
“MessagePartDescription Name ='GetWhatsResult'的实例无法在此上下文中使用:必需'Type'属性未设置。
如果我拿出DataContract并注释掉服务定义中的函数,我很好。我不打算在Excel中使用GetWhats()
函数。但是我猜想它需要TheWhats
的类型定义。
从我读过的一个解决方案似乎是使这个COM对象,并引用该DLL。但是,这不适合我的环境。有其他方法可以解决这个问题吗?
昨晚我又有一个念头。假设我创建了两个不同的接口 - 一个是Excel可以安全调用的“只写”接口,而不用担心额外的类,另外一个“服务”接口向客户端提供更多详细信息,包括此类定义。这样,Excel永远不需要知道数据合同以及什么 - 它只会将一个字符串发布到一个服务上并且完成它。 – mounty