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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文地址:https://www.cnblogs.com/prinsun/p/2638329.html