最近有个项目需要从Excel中调用Web Service, Google 了一翻果然可以,总结如下:
一、安装开发包。
要从Excel中通过宏调用Web Service,需要安装Microsoft Office 2003 Web Services Toolkit 2.01,可从这里下载,下载 。
二、调用Web Service
安装好开发包以后,调用Web Service就变得很容易了,操作跟在VS 2003中差不多。切换到宏编辑器(Visual Basic Editor),从Tools菜单中点击“Web Service Reference”打开添加Web service引用的对话框。添加好引用后,开发包就会自动为你封装好一些用Soap调用Web Service的相关类。调用这些类中的相关方法就可以调用Web Service方法了。
三、读写SoapHeader内容
有些Web Service需要提供SoapHeader内容,比如通过SoapHeader提供帐号信息以供服务端验证客户身份。下面就是一个例子
服务端:
自定义SoapHeader类:
Web Service方法:
客户端:
定义一个专门的类用于封装对SoapHeader的操作,类名为clsAccountHeader:
Option Explicit
Implements IHeaderHandler
Private Const NameSpace As String = "http://tempuri.org/"
Private myUserName As String
Private myPassword As String
Public Property Let UserName(ByVal name As String)
myUserName = name
End Property
Public Property Get UserName() As String
UserName = myUserName
End Property
Public Property Let Password(ByVal password1 As String)
myPassword = password1
End Property
Public Property Get Password() As String
Password = myPassword
End Property
Private Function IHeaderHandler_ReadHeader( _
ByVal pReader As SoapReader30, _
ByVal pHeaderNode As MSXML2.IXMLDOMNode, _
ByVal pObject As Object) _
As Boolean
IHeaderHandler_ReadHeader = False
End Function
Private Function IHeaderHandler_WillWriteHeaders() As Boolean
IHeaderHandler_WillWriteHeaders = True
End Function
'<ServiceHead xmlns="http://tempuri.org/">
' <UserName>string</UserName>
' <Password>string</Password>
'</ServiceHead>
Private Sub IHeaderHandler_WriteHeaders(ByVal pSerializer As SoapSerializer30, ByVal pObject As Object)
'Dim doc As New MSXML2.DOMDocument40
'Create the string for UserInfoRouteHeader.
Dim userDoc As String
userDoc = "<ServiceHead xmlns=""" & NameSpace & """>"
If myUserName <> "" Then
userDoc = userDoc & "<UserName>" & myUserName & "</UserName>"
End If
If myPassword <> "" Then
userDoc = userDoc & "<Password>" & myPassword & "</Password>"
End If
userDoc = userDoc & "</ServiceHead>"
pSerializer.WriteXml userDoc
End Sub
在调用Web Service方法时提供SoapHeader内容:
关于读SoapHeader的实现可参考婷篇文章:利用 SOAP 头保持 EJB 状态(http://www.ibm.com/developerworks/cn/webservices/ws-ejbsoap/index.html)
一、安装开发包。
要从Excel中通过宏调用Web Service,需要安装Microsoft Office 2003 Web Services Toolkit 2.01,可从这里下载,下载 。
二、调用Web Service
安装好开发包以后,调用Web Service就变得很容易了,操作跟在VS 2003中差不多。切换到宏编辑器(Visual Basic Editor),从Tools菜单中点击“Web Service Reference”打开添加Web service引用的对话框。添加好引用后,开发包就会自动为你封装好一些用Soap调用Web Service的相关类。调用这些类中的相关方法就可以调用Web Service方法了。
三、读写SoapHeader内容
有些Web Service需要提供SoapHeader内容,比如通过SoapHeader提供帐号信息以供服务端验证客户身份。下面就是一个例子
服务端:
自定义SoapHeader类:
public class ServiceHead : System.Web.Services.Protocols.SoapHeader
{
private string userName;
private string password;
public string UserName
{
get { return userName; }
set { userName = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
}
{
private string userName;
private string password;
public string UserName
{
get { return userName; }
set { userName = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
}
Web Service方法:
[WebMethod(Description = "User name and password are reuired!")]
[SoapHeader("accountHead")]
public MonthPriceCol GetPriceInfo(string pSymbol,string pBeginDate,string pEndDate)
{
.
if(!CheckUserIdentity(accountHead)) return null;
.
}
[SoapHeader("accountHead")]
public MonthPriceCol GetPriceInfo(string pSymbol,string pBeginDate,string pEndDate)
{
.
if(!CheckUserIdentity(accountHead)) return null;
.
}
客户端:
定义一个专门的类用于封装对SoapHeader的操作,类名为clsAccountHeader:
Option Explicit
Implements IHeaderHandler
Private Const NameSpace As String = "http://tempuri.org/"
Private myUserName As String
Private myPassword As String
Public Property Let UserName(ByVal name As String)
myUserName = name
End Property
Public Property Get UserName() As String
UserName = myUserName
End Property
Public Property Let Password(ByVal password1 As String)
myPassword = password1
End Property
Public Property Get Password() As String
Password = myPassword
End Property
Private Function IHeaderHandler_ReadHeader( _
ByVal pReader As SoapReader30, _
ByVal pHeaderNode As MSXML2.IXMLDOMNode, _
ByVal pObject As Object) _
As Boolean
IHeaderHandler_ReadHeader = False
End Function
Private Function IHeaderHandler_WillWriteHeaders() As Boolean
IHeaderHandler_WillWriteHeaders = True
End Function
'<ServiceHead xmlns="http://tempuri.org/">
' <UserName>string</UserName>
' <Password>string</Password>
'</ServiceHead>
Private Sub IHeaderHandler_WriteHeaders(ByVal pSerializer As SoapSerializer30, ByVal pObject As Object)
'Dim doc As New MSXML2.DOMDocument40
'Create the string for UserInfoRouteHeader.
Dim userDoc As String
userDoc = "<ServiceHead xmlns=""" & NameSpace & """>"
If myUserName <> "" Then
userDoc = userDoc & "<UserName>" & myUserName & "</UserName>"
End If
If myPassword <> "" Then
userDoc = userDoc & "<Password>" & myPassword & "</Password>"
End If
userDoc = userDoc & "</ServiceHead>"
pSerializer.WriteXml userDoc
End Sub
Private Sub Class_Initialize()
'*****************************************************************
'This subroutine will be called each time the class is instantiated.
'Creates sc_ComplexTypes as new SoapClient30, and then
'initializes sc_ComplexTypes.mssoapinit2 with WSDL file found in
'http://172.20.18.191/StockService/StockService.asmx?wsdl.
'*****************************************************************
Dim myAccount As New clsAccountHeader
Dim str_WSML As String
str_WSML = "<servicemapping>"
str_WSML = str_WSML & "<service name='StockService'>"
str_WSML = str_WSML & "<using PROGID='MSOSOAP.GenericCustomTypeMapper30' cachable='0' ID='GCTM'/>"
str_WSML = str_WSML & "<types>"
str_WSML = str_WSML & "<type name='StockMonthPrice' targetNamespace='http://tempuri.org/' uses='GCTM' targetClassName='struct_StockMonthPrice'/>"
str_WSML = str_WSML & "</types>"
str_WSML = str_WSML & "</service>"
str_WSML = str_WSML & "</servicemapping>"
Set sc_StockService = New SoapClient30
sc_StockService.MSSoapInit2 c_WSDL_URL, str_WSML, c_SERVICE, c_PORT, c_SERVICE_NAMESPACE
'Use the proxy server defined in Internet Explorer's LAN settings by
'setting ProxyServer to <CURRENT_USER>
sc_StockService.ConnectorProperty("ProxyServer") = "<CURRENT_USER>"
'Autodetect proxy settings if Internet Explorer is set to autodetect
'by setting EnableAutoProxy to True
sc_StockService.ConnectorProperty("EnableAutoProxy") = True
Set sheet = ActiveWorkbook.Sheets("Tickers")
myAccount.UserName = sheet.txtEmail.Value
myAccount.Password = sheet.txtPassword.Value
Set sc_StockService.HeaderHandler = myAccount
Set sc_StockService.ClientProperty("GCTMObjectFactory") = New clsof_Factory_StockService
End Sub
'*****************************************************************
'This subroutine will be called each time the class is instantiated.
'Creates sc_ComplexTypes as new SoapClient30, and then
'initializes sc_ComplexTypes.mssoapinit2 with WSDL file found in
'http://172.20.18.191/StockService/StockService.asmx?wsdl.
'*****************************************************************
Dim myAccount As New clsAccountHeader
Dim str_WSML As String
str_WSML = "<servicemapping>"
str_WSML = str_WSML & "<service name='StockService'>"
str_WSML = str_WSML & "<using PROGID='MSOSOAP.GenericCustomTypeMapper30' cachable='0' ID='GCTM'/>"
str_WSML = str_WSML & "<types>"
str_WSML = str_WSML & "<type name='StockMonthPrice' targetNamespace='http://tempuri.org/' uses='GCTM' targetClassName='struct_StockMonthPrice'/>"
str_WSML = str_WSML & "</types>"
str_WSML = str_WSML & "</service>"
str_WSML = str_WSML & "</servicemapping>"
Set sc_StockService = New SoapClient30
sc_StockService.MSSoapInit2 c_WSDL_URL, str_WSML, c_SERVICE, c_PORT, c_SERVICE_NAMESPACE
'Use the proxy server defined in Internet Explorer's LAN settings by
'setting ProxyServer to <CURRENT_USER>
sc_StockService.ConnectorProperty("ProxyServer") = "<CURRENT_USER>"
'Autodetect proxy settings if Internet Explorer is set to autodetect
'by setting EnableAutoProxy to True
sc_StockService.ConnectorProperty("EnableAutoProxy") = True
Set sheet = ActiveWorkbook.Sheets("Tickers")
myAccount.UserName = sheet.txtEmail.Value
myAccount.Password = sheet.txtPassword.Value
Set sc_StockService.HeaderHandler = myAccount
Set sc_StockService.ClientProperty("GCTMObjectFactory") = New clsof_Factory_StockService
End Sub
关于读SoapHeader的实现可参考婷篇文章:利用 SOAP 头保持 EJB 状态(http://www.ibm.com/developerworks/cn/webservices/ws-ejbsoap/index.html)