• Delphi 调用金蝶登录,并解析PropsString


    此篇日志,是上一篇日志的兄弟篇,下面是我使用Delphi2010封装的一个单元,直接使用即可,其解析算法和前两篇中的一致,可供Delphi进行金蝶二次开发的人员参考。

    {
     Design By M.K
     Create At 2012.08.14
    }
    
    unit KingdeeUtils;
    
    interface
    
    uses SysUtils, ComObj, Generics.Collections;
    
    type
      TKingdeeLogin = class(TObject)
    
      private
        _clsLogin: OleVariant;
        _connectionString: string;
        _accountName: string;
        _userName: string;
        _userId: Integer;
    
        procedure InitialLoginDatas;
        procedure ParsePropsStringToField(propsString: string);
    
        function ReadPropsStringToDictionary(propsString: string): TDictionary<string, string>; 
        function ReadSection(sections: TDictionary<string, string>; source: string): Integer;
        function ReadKey(source: string; var key: string): Integer;
        function ReadValue(source: string; var value: string): Integer;
        function GetValueFromDictionary(key: string; source: TDictionary<string, string>): string;
        
      public
        constructor Create;
        function CheckLogin: Boolean;
    
        property ConnectionString: string read _connectionString;
        property AccountName: string read _accountName;
        property UserName: string read _userName;
        property UserID: Integer read _userId; 
      end;
    
    
    implementation
    
    { TKingdeeLogin }
    
    constructor TKingdeeLogin.Create;
    begin
      _clsLogin := CreateOleObject('K3Login.ClsLogin');
    end;
    
    function TKingdeeLogin.CheckLogin: Boolean;
    begin
       Result := _clsLogin.CheckLogin;
       if Result then InitialLoginDatas;
    end;
    
    procedure TKingdeeLogin.InitialLoginDatas;
    begin
      _accountName := _clsLogin.AcctName;
      ParsePropsStringToField(_clsLogin.PropsString); 
    end;
    
    
    {$REGION '解析PropsString'}
    
    procedure TKingdeeLogin.ParsePropsStringToField(propsString: string);
    var
      datas: TDictionary<string, string>;
    begin
      datas := ReadPropsStringToDictionary(propsString);
    
      _userName := GetValueFromDictionary('UserName', datas);
      _userId := StrToInt(GetValueFromDictionary('UserID', datas));
      _connectionString := GetValueFromDictionary('ConnectString', datas); 
    
      //这里大家可以继续扩展,因为PropsString里面还有很多字段。   
    
      datas.Free;
    end;
    
    function TKingdeeLogin.ReadPropsStringToDictionary(
      propsString: string): TDictionary<string, string>;
    var
      dicResult: TDictionary<string, string>;
      curIndex: Integer;   
    begin
      dicResult := TDictionary<string, string>.Create;
      curIndex := 0;
      
      while curIndex < Length(propsString) do
        curIndex := curIndex 
                 + ReadSection(dicResult, 
                 Copy(propsString, curIndex + 1, Length(propsString) - curIndex));
      
       Result := dicResult;
    
    end;
    
    function TKingdeeLogin.ReadSection(sections: TDictionary<string, string>;
      source: string): Integer;
    var
      lengthResult: Integer;
      key, value: string;
    begin
      lengthResult := 0;
    
      lengthResult := lengthResult + ReadKey(source, key);
      lengthResult := lengthResult 
                    + ReadValue(Copy(source, lengthResult + 1, Length(source) - lengthResult), value);
      
      sections.Add(key, value);
    
      Result := lengthResult;
    end;
    
    function TKingdeeLogin.ReadKey(source: string; var key: string): Integer;
    var
      i, lengthResult: Integer;
    begin
      key := '';
      lengthResult := 0;
    
      for i := 1 to Length(source) do
      begin
        lengthResult := i;
        if source[i] = Char('=')  then
            Break
        else
            key := key + source[i];
      end;
    
      Result := lengthResult;
    end;
    
    function TKingdeeLogin.ReadValue(source: string; var value: string): Integer;
    var
      i, lengthResult: Integer;
      charStack: TStack<Char>;
      c: Char;
    begin
      value := '';
      lengthResult := 0;
      charStack := TStack<Char>.Create;
      
      for i := 1 to Length(source) do
      begin
        c := source[i];  
        lengthResult := i;
    
        if c = Char('{') then
        begin
          if charStack.Count > 0 then value := value + c;
          charStack.Push(c);
        end
        else if c = Char('}') then
        begin
          charStack.Pop;
          if charStack.Count > 0 then value := value + c;
        end
        else if c = Char(';') then
        begin
          if charStack.Count > 0 then
            value := value + c
          else
            Break;
        end
        else
        begin
          value := value + c;
        end;
      end;
      
      Result := lengthResult;     
      charStack.Free;
      
    end;
    
    function TKingdeeLogin.GetValueFromDictionary(key: string;
      source: TDictionary<string, string>): string;
    var
      dicKey, sKey: string;
    begin
      dicKey := '';
      for sKey in source.Keys do
      begin
        if UpperCase(Trim(key)) = UpperCase(Trim(sKey)) then
        begin
          dicKey := sKey;
          Break;
        end;
      end;
    
      if dicKey = '' then 
        Result := ''
      else
        Result := source[dicKey];
    end;
    
    {$ENDREGION}
    
    end.

    调用方式:

    procedure TFrmMain.btnGetConnectionStringClick(Sender: TObject);
    var
      clsLogin: TKingdeeLogin;
    begin
      try
        clsLogin := TKingdeeLogin.Create;
        if clsLogin.CheckLogin then
          begin
            ConnectionString := clsLogin.ConnectionString ;
            mmoConnectionString.Text := ConnectionString;
            lbledtUserName.Text := clsLogin.UserName;
            lbledtAccountName.Text := clsLogin.AccountName;
          end
        else
          ShowMessage('UnLogin!');
    
        clsLogin.Free;
      except
        ShowMessage('必须在安装了金蝶的客户端上运行!');
      end;
    end;

    调用,差不多就和上面类似,当然,也可以放在Project文件中,从入口处来处理程序的逻辑,通过判断是否登录,来决定是否运行主窗体。

    至此,关于金蝶登录,并取得ConnectionString的例子算是比较完善了,至于接下来怎么做,我比较喜欢直接对数据库动刀,而不是调用金蝶提供的API接口,所以,基本上我需要一个ConnectionString和UserID就足够了。

    作者:Sun.M
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    ios 动态库加载及某个文件非ARC问题
    block循环引用用__weak声明
    nib加载方式
    UIImage两种加载方式
    xcode头文件编译错误
    ios 工程的相对路径
    ios的window.rootViewController的更换
    Header Search Paths找不到
    mac下svn问题 —— “.a”(静态库)文件无法上传的 简单处理办法
    UIPickerView 和 UIDatePicker常用方法, 程序启动的完整过程
  • 原文地址:https://www.cnblogs.com/prinsun/p/2638329.html
Copyright © 2020-2023  润新知