【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)

  最近接口项目需要用PB调用SAP的Web Service,研究了PB的Webservice Proxy很久。

  第1个问题是SAP的Web Service有身份验证,主程序是PB9开发的,pbsoapclient90.pbd里没有对应函数,说是需要PB10以上,PB11.5经验证可以解决。或者安装微软SOAP工具控件,PB9通过它调用Web Service也是可以的。

  但核心问题来了:SAP的Web Service函数中参数实际传输的是Table,也就是结构体数组参数。测试证明,即使PB12.5都对结构体参数的Web Service支持不完善,就不要说结构体数组了!

  肿么办?研究发现,我们可以使用C#调用结构体数组参数的Web Service,然后拆解为单结构体,转换为字符串数组参数,封装为DLL函数,供PB调用。这种方式理论上,应该适用于PB的任何版本。

  ——by nocry115/泥草鞋


  这里,我们以VS2010 C#与PB9进行说明;将对方Web Service的WSDL文件拷贝到本地,这个Web Service定义了1个函数,其参数为结构体数组,返回一个含2字符串的结构体。

1、使用C#调用Web Service生成dll

  1)首先,新建Visual C#的“类库”项目,我们可以命名为:sapws1(注意:C#区别大小写)。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第1张图片

  双击改项目的属性Properties,在“应用程序”页面点击【程序集信息】。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第2张图片

  在“为COM互操作注册”处打钩。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第3张图片

  并在“生成”页面在“使程序COM可见”处打钩。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第4张图片

  以上是为生成供调用的Dll做准备,保存后我们可以在属性下的AssemblyInfo.cs处查看ComVisible是否为true。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第5张图片


  2)这一步即引用SAP的Web service。我们在解决方案的【引用】项处右键点击“添加服务引用”。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第6张图片

  注意,这一步很关键,不能在这个界面直接引用,而应该点击【高级】按钮。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第7张图片

  在接下来的服务引用设置界面,再点击【添加Web引用】(SAP的Web service基于简单SOAP协议)。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第8张图片

  在“添加Web引用”界面,“URL”输入本地wsdl文件并点击右侧箭头;在身份验证弹出框输入账号口令,即可看到对方的Web service服务名是SI_03AA6_SNZYXT2ERP_JHDGBService,其函数/方法为SI_03AA6_SNZYXT2ERP_JHDGB()。这里,我们把该服务命名为“ws1”。然后点击【添加引用】。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第9张图片

  在“解决方案资源管理器”中我们可以看到ws1已经加入,双击ws1我们可以在“对象浏览器”中查看其函数具体的格式定义。参数其中有结构体数组ZSSD_JHDGB[];结构体ZSSD_JHDGB的构成也可在“对象浏览器”中查看。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第10张图片


  3)双击“Class1.cs”进行代码编写:

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第11张图片

  这里,我们需要在using引用区加1行,并替换到中间的Class1类;代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;    //该引用必须

namespace sapws1    //命名空间
{
    [Guid("5690DF0B-0DF9-49CC-AF63-22DF5D0A5F04")]   //利用工具->创建GUID->生成器5随机生成
    public interface CallParamers
    {
        [DispId(1)] //接口方法的绑定号
        string PBSAP(string uname, string upass, string[] arrs, ref string rets);//
    }

    [Guid("CF41B4E8-C463-40CB-B7F0-8D1F1999E83B")]   //利用工具->创建GUID->生成器5随机生成
    [ClassInterface(ClassInterfaceType.None)]
    public class Class1 : CallParamers
    {
        public string PBSAP(string uname, string upass, string[] arrs, ref string rets)
        {
            ws1.ZSSD_JHDGB[] sz1;
            sz1 = new ws1.ZSSD_JHDGB[1]; //结构体数组参数定义
            ws1.ZSSD_JHDGB sj;
            sj = new ws1.ZSSD_JHDGB(); //分解为单一结构
            //对结构数据赋值
            sj.VBELN = arrs[0]; 
            sj.POSNR = arrs[1];
            sj.LFIMG = Convert.ToDecimal(arrs[2]);
            sj.LFIMGSpecified = true; //decimal类型
            
            sj.WADAT = arrs[3];  //提货日期
            sj.WADAT_IST = arrs[4]; //发货日期
            sj.DATA01 = arrs[5];   //预留字段1
            sj.DATA02 = arrs[6];   //
            sj.DATA03 = arrs[7];   //
            sj.DATA04 = arrs[8];   //
            sj.DATA05 = arrs[9];   //
            sj.DATA06 = arrs[10];   //
            sj.DATA07 = arrs[11];   //
            sj.DATA08 = arrs[12];   //
            sj.DATA09 = arrs[13];   //
            sj.DATA10 = arrs[14];   //

            sz1[0] = sj; //对结构数组赋值
   
            //调用SAP Web Service 
            ws1.SI_03AA6_SNZYXT2ERP_JHDGBService s = new ws1.SI_03AA6_SNZYXT2ERP_JHDGBService();
            //Web Service身份验证
            System.Net.NetworkCredential c = new System.Net.NetworkCredential(uname, upass);
            s.Credentials = c; //
            string rs2;
            string rs1 = s.SI_03AA6_SNZYXT2ERP_JHDGB(ref sz1, out rs2); //调用Web Service函数
            rets = rs1;
            return rs2;
        }
    }
}
  说明:全球唯一码GUID可用VS2010菜单【工具】-【创建GUID】来生成;选择第5种方式,复制替换即可。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第12张图片

  说明:“[DispId(1)]”项定义dll函数序数,如果有第2个函数,同法定义[DispId(2)]”,函数说明与主函数相同。

  说明:结构体成员数必须与数组成员数对等;注意C#数组标从0开始。

  说明:webService结构体中的数值型成员,引入到C#中将多出bool形私有成员,请设为true,并将字符串转换为对应数值。

  最后,生成该项目即可。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第13张图片

2、初始化DLL环境

  建立PB调用目录c:\wssap;将生成的dll与tlb文件拷贝出来,默认在项目的bin\Debug目录下。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第14张图片

  并找到.Net 4.0下的RegAsm.exe文件,也拷贝到该目录。然后在操作系统运行cmd,输入:

regasm sapws1.dll  /tlb:sapws1.tlb

  回车显示成功注册信息。

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第15张图片


3、用PB调用C#的dll

  在PB中调用该C#DLL,代码如下:

string ls_ret, ls_msg, ls_uname, ls_upass
string	 sz[] //用数组代替结构
int i, ii
 
OleObject OleSAP
OleSAP = Create OLEObject
//sapws1为C#中命名空间(namespace) ,Class1为C#中类名
i = OleSAP.ConnectToNewObject("sapws1.Class1") 
if i <>0 then
    MessageBox("提示","PB调用C#COM组件(SAP.WebService)失败!")
    return
end if

//初始化
ii = 15 //数组成员与结构体成员相同
for i = 1 to ii
	sz[i] = "" 
Next
//数据测试
sz[1] = "1000066666"
sz[2] = "000010"
sz[3] = "88"
//SAP Webservice账号口令
ls_uname	= "zzsoap"
ls_upass		= "shenhua"
 
ls_ret =OleSAP.PBSAP(ls_uname, ls_upass, sz, ref ls_msg)

MessageBox(ls_ret, ls_msg)

  看看运行结果:

【原创】PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)_第16张图片



你可能感兴趣的:(Powerbuider+Web)