ラベル へなちょこTips XE の投稿を表示しています。 すべての投稿を表示
ラベル へなちょこTips XE の投稿を表示しています。 すべての投稿を表示

2011年4月3日日曜日

Guid文字列を得る

Delphiで、Guidを得るには、通常の場合CreateGuid手続きを使用します。
また、Guid文字列を得るする場合には、GuidToString手続きを使用して文字列に変換します。

procedure TForm1.Button1Click(Sender: TObject);
var
  guid : TGuid;
begin
  CreateGuid(guid);
  LabeledEdit1.Text := GuidToString(guid);

end;


Delphi XEでは、TGuid型に対して、TGuidHelperクラスが実装されているので
このHelperを利用してもGuidを得ることができます。
(Helperは.Net FrameworkのGuid構造体と同じ動きをするように実装されている
ようです。但し、.Net側のToStringメソッドでは文字列が中括弧で囲まれないので
注意が必要かなぁ?)

procedure TForm1.Button2Click(Sender: TObject);
var
  guid:TGUID;
  S:String;
begin
  guid := TGUID.NewGuid;
  LabeledEdit1.Text := guid.ToString;
end;


TGuidHelperクラスにはGuidの表現形式に応じていくかのCreate関数が用意されていますで
プログラム中で使用している表現形式からGUDIの生成が可能です。

下記の例は、文字列で表現されたGUIDからTGuid型の変数を得る例です。

procedure TForm1.Button3Click(Sender: TObject);
var
  guid:TGUID;
begin
 guid := TGUID.Create('{1F447130-60E2-40A0-9A00-EB94C1C7D691}');
  label1.Caption := guid.Tostring; //{1F447130-60E2-40A0-9A00-EB94C1C7D691}が表示される
end;

2011年4月1日金曜日

ClientDatasetのでも

Buleberry社のFlashBack ExpressのテストでClientDataSetのチョットしたサンプル動画(スクリーンキャプチャー)を
作ってみた。

サンプルの内容は、IDE上でクライアントデータセットのフィールドを作成し

Delphiのプログラムでデータをセットするものです。

編集もなにもしてないので、チョットまのびした動画になっちゃてます。


2011年3月1日火曜日

Null許容型

delphilhlplibの中にNull許容型が容易されてるのでちょっと試してみた。

delpjihlplibは上記のリンクから最新のモジュールをダウンロードして
パッケージをインストールすることで使用可能になります。

以下試したソースコード

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation
Uses DeHL.Nullable;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i : Nullable <integer>
begin

  //値を代入する前はNULL
  if i.IsNull then
  begin
    Label1.Caption := 'Null';
  end;

  //値を代入すると普通の型のように扱える
  i.Value := 100;
  Label2.Caption := IntToStr(i);

  //MakeNullでNullをセットできるようだ。
  i.MakeNull;

  if i.IsNull then
  begin
    Label3.Caption := 'Null';
  end;

end;

end.

delphihelplibには、そのほかにもいろいろなクラスがあるようなので、追々試してみようと思う。

2011年2月6日日曜日

Unified Interbaseコンポーネントをつかってみた(その3)

Unified Interbaseコンポーネントをつかってみた(その1)でUIBDataSet経由でDBグリッドに
データを表示した。

しかし、UIBDataSetはReadOnlyのデータセットなので、編集が不可となっています。
(前回のサンプルを実行してもグリッドに入力ができません。)

いくつか、実験をおこなった結果、UIBDataSetは、単方向データセットとして機能している
ようなので、ClientDataSetを経由で接続すれば、DbExpressドライバのように使えるはず
だと思い試してみた。

以下、試して確認できたことを備忘録代わりに記述

フォームにTClientDataSetコンポーネントとTDataSetProviderコンポーネントを配置し、
UIBDataset → DatasetProvieder → ClientDataset → DataSourceにリンク変更


ここで、ClientDataset をActiveにするとタイムスタンプがうまく処理できないようでエラーが
発生するので、ClinetDataSet、およびUIBDataSetのソースを調べた結果、以下のとおり
データ形式の不整合があった。

UIBDataSet -> TDatetime型
ClinetDataSet → 通算のミリ秒(ftDatetime指定時)

そこで、ClientDatasetと時刻データが正しく連携が取れるようUIBDataSetを拡張したコンポーネントで、接続した。
以下、ソース

unit UIBCdsDataSet;

interface

uses
  SysUtils, Classes, DB, uibdataset;

type
  TUIBCdsDataSet = class(TUIBDataSet)
  private
    { Private 宣言 }
  protected
    { Protected 宣言 }
  public
    { Public 宣言 }
    function GetFieldData(FieldNo: Integer; Buffer: Pointer): Boolean; overload;{$IFNDEF FPC} override; {$ENDIF}
    {$IFNDEF FPC}
    function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload; override;
    {$ENDIF}
  published
    { Published 宣言 }
  end;

procedure Register;

implementation

uses uiblib;

procedure Register;
begin
  RegisterComponents('UIB', [TUIBCdsDataSet]);
end;

{ TUIBCdsDataSet }

function TUIBCdsDataSet.GetFieldData(FieldNo: Integer;
  Buffer: Pointer): Boolean;
var
  doubleBuf : TDateTime;
  aFieldType: TUIBFieldType;
  tsbuf : TTimeStamp;
begin

 Result := inherited GetFieldData(FieldNo, Buffer);
  if not(Result) then Exit;
  if Buffer = nil then Exit;

  aFieldType := Self.InternalFields.FieldType[FieldNo -1];

  if aFieldType = uftTimestamp then
  begin
   doubleBuf := TDateTime(Buffer^);
    tsbuf := DateTimeToTimeStamp(doubleBuf);

   Double(Buffer^) :=  TimeStampToMSecs(tsbuf);
 end;
end;

function TUIBCdsDataSet.GetFieldData(Field: TField; Buffer: Pointer;
  NativeFormat: Boolean): Boolean;
var
 //SF : TSQLResult;
  doubleBuf : TDateTime;
  aFieldType: TUIBFieldType;
  tsbuf : TTimeStamp;
begin

  Result := inherited GetFieldData(Field, Buffer,NativeFormat);
  if not(Result) then Exit;
  if Buffer = nil then Exit;

  //SF := Self.InternalFields;
  aFieldType := Self.InternalFields.FieldType[Field.FieldNo-1];

  if aFieldType = uftTimestamp then
  begin
   doubleBuf := TDateTime(Buffer^);
    tsbuf := DateTimeToTimeStamp(doubleBuf);

   Double(Buffer^) :=  TimeStampToMSecs(tsbuf);
  end;

end;

end.

これで時刻型のフィールドでエラーが発生することなく連携ができた。

2011年1月27日木曜日

Unified Interbaseコンポーネントをつかってみた(その1)

Unified Interbaseコンポーネントは、Delphi XE対応のInterbase, Firebird接続用のコンポーネントです。
FB2.5にも対応しているということなのでちょっと試してみたので備忘録代わりに記述

先ずは、インストール

Unified Interbaseのリポジトリからファイルをダウンロード

ダウンロードしたZIPファイルを適当なフォルダに展開し、パッケージフォルダから
UIBD15Win32.groupprojを開く。

開発時パッケージUIBD15Win32D.bplをインストール
エラーが発生しなければ

下図のようにツールパレットにコントロールが登録されます。



Firebirdに接続してみる。

フォームにTUIBDatabaseコンポーネントを配置して右クリックを押すと
接続エディタが表示されるので、接続情報を入力する。
テストボタンで接続をテストすることができます。


UIBDataSetコンポーネントを配置しDatabsaeプロパティにUIBDatabseを指定します。
SQLプロパティにSQL文を記述します。

次に、UIBTransactionプロパティを配置し、DatabaseプロパティにUIBDatabseを指定します。
(UIBTransactionは、きめ細かい設定ができるようなのですが、ここではそのまま使います。)

また、UIBDataSetコンポーネントのTransactionプロパティにUIBTransactionを指定します。

あとは、DataSourceコンポーネントを介してDatabaseコントロールと接続します。

UIBDatabseのConnectedプロパティと、UIBDatasetのActiveプロパティをTrueにすれば
下図のようにデータが読み込めます。

2010年11月3日水曜日

サービスの起動と停止

現在、進行中の案件で、サービスの再起動を定期的に行う必要が
あるので、Delphiでできるかどうか調べてみた。

Delphi PrismではdotNetFreameworkに標準で用意されたクラスが使えるので
簡単だが、Delphi(Win32)では用意されていないみたいだ。

さらに調べたところ、Jedi Code Library(Jcl)には、サービスを扱うクラス
(TJclSCManager,TJclNTService)が用意されていることを知ったので、
実際に検証してみた。

以下、検証用に作ったサンプル(サービスの列挙と指定したサービスの
停止と起動)です。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    LabeledEdit1: TLabeledEdit;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
    JclSvcCtrl
  , TypInfo
  ;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  SvcMgr : TJclSCManager;
  i : Integer;
begin
//
  SvcMgr := TJclSCManager.Create();

  try
    SvcMgr.Refresh(true);
    ListBox1.Clear;
    for i := 0 to SvcMgr.ServiceCount -1 do
    begin
      ListBox1.Items.Add(SvcMgr.Services[i].ServiceName);
    end;


  finally
    SvcMgr.Free;
  end;

end;

procedure TForm1.Button3Click(Sender: TObject);
var
  SvcMgr : TJclSCManager;
  Svc : TJclNTService;
begin
//
  //if True then
  SvcMgr := TJclSCManager.Create();
  try
    SvcMgr.Refresh(true);
    if (SvcMgr.FindService(LabeledEdit1.Text,Svc)) Then
    begin
      if TComponent(Sender).Tag = 1 then
      begin
        Svc.Start;
      end
      else
      begin
        Svc.Stop;
      end;
      Label1.Caption := GetEnumName(TypeInfo(TJclServiceState),Ord(Svc.ServiceState)) ;
    end;
  finally
    SvcMgr.Free;
  end;


end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  SvcMgr : TJclSCManager;
  Svc : TJclNTService;
begin
  if ListBox1.ItemIndex >=0 then
  begin
    LabeledEdit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];
    SvcMgr := TJclSCManager.Create();
    try
      SvcMgr.Refresh(true);
      if (SvcMgr.FindService(LabeledEdit1.Text,Svc)) Then
      begin
        Label1.Caption := GetEnumName(TypeInfo(TJclServiceState),Ord(Svc.ServiceState));
      end;
    finally
      SvcMgr.Free;
    end;

  end;

end;

end.




なお、jclには上記クラスを使用したサンプルプログラムがありますので詳細については
そちらを参照して下さい。

2010年9月5日日曜日

JoinStringはないの?

VB6のJoin関数および.Net FrameworkのString.Joinメソッドは、
XEで追加されたほどSplitString使用頻度は多くないがたまに必要に
なることがある。

Help,ソースをざっくり見たところなさそうだったので実装してみた。
(といっても文字列を連結しただけですが・・・)

以下、ソースコード

unit VbLikeStringUtil;

interface

uses
  StrUtils,Types;

  function JoinString(AStrings: TStringDynArray; Delemeter : String) : String;

implementation

uses
  SysUtils;

function JoinString(AStrings: TStringDynArray; Delemeter : String) : String;
var
  i : Longint;
begin

  Result := '';
  for i := low(AStrings) to high(AStrings) do
  begin
    Result := Result + AStrings[i];
    if i < high(AStrings) then Result := Result + Delemeter;
  end;


end;

end.



実際の使用方法のサンプルは、こんな感じ

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  StrUtils,Types, VbLikeStringUtil;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  JoinItems : TStringDynArray;
begin


  SetLength(JoinItems,5);

  JoinItems[0] := 'イージス';
  JoinItems[1] := 'ジャスティス';
  JoinItems[2] := 'ザク';
  JoinItems[3] := 'セイバー';
  JoinItems[4] := 'グフ';


  Label1.Caption := JoinString(JoinItems,'|');


end;

end.

2010年9月3日金曜日

SplitStringを試してみる。

Delphi XEでSplitString関数が追加された。VBにあって、Delphiになかった関数で
個人的には気になってた関数です。(欲しかった関数です。)

で、ちょっとためしてみた。

以下、ソースコード

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  StrUtils,Types;

procedure TForm1.Button1Click(Sender: TObject);
var
  TestString : String;
  SplitResult:TStringDynArray;
begin
  TestString := 'フリーダム,ジャスティス,デストロイ,セイバー';
  SplitResult := SplitString(TestString,',');
  Label1.Caption := TestString;

  for TestString in SplitResult do begin
    ListBox1.Items.Add(TestString);
  end;

end;

end.


Visual Basicライクで非常に簡単に使えます。

内部的には、FindDelimiter関数を使ってDelemeterをみつけ
Copy関数で部分文字列を切り出してます。

これなら、下位バージョンでも実装できそうですね。

ところでFindDelimiter関数は、いつから存在したのでしょうか?
個人的には、Delphiにはまだまだ知らない便利な関数が一杯ありそうです。


2010.09.10 山本隆の開発日記で紹介して頂いたので
調子にのってC++ Builderで書いてみました。
(C++は自信がないので、役に立つかどうかわかりませんが・・・)

//---------------------------------------------------------------------------

#include 
#include 
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
 : TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

 UnicodeString TestString = "イージス|バスター|デュエル|ブリッツ|ストライク";

 LabeledEdit1->Text = TestString;

 TStringDynArray SplitResult = SplitString(TestString,"|");

 for (int i = 0; i < SplitResult.Length; i ++) {
  ListBox1->Items->Add(SplitResult[i]);
 }

 SplitResult.set_length(0);

}
//---------------------------------------------------------------------------