愚者の経験

「また今度」はほとんどこない

月別アーカイブ: 12月 2011

Silverlightとデータベース

参考URL:http://www.slideshare.net/odashinsuke/silverlightwp7-db

基幹業務系のソフトを作る場合、データベースを利用はさけて通れません。
Silverlightでローカルデータベースを扱う場合どうすればいいか探してみます。

1.「Silverlight COM Toolkit」→ほぼADODB
2.「C#SQLite」→Android等でお世話になっているSQLite
3.「siaqodb」→有料?
4.「Sterling」→参考URLでは推し。WindowsPhone関連でも結構取り上げられてます。

しかしほとんど全部の記事が英語です。英語できない自分にはかなり辛い…

というかSQL Server CE 使わせてほしい…orz

MSDataShape その3

前回の記事:MSDataShape その2で子のRecordsetを持った列が追加されたところを紹介しました。
今回「列が追加された」にフォーカスを当て、更に別の機能を紹介します。

本来「MSDataShape」サービスプロバイダは階層化Recordsetを作ることが目的だと思いますが、
子のレコードセット列を追加する以外にも、任意のデータ型の列を追加できます。

    rst.Open “SHAPE {select * from table1} APPEND NEW adLongVarWChar as field1”

「NEW adLongVarWChar as field1」でなんとなくお分かりとは思いますが、
「select * from table1」で取得した列に加えて、「field1」という列も追加されます。
データ型は「adLongVarWChar」で文字列型(SQLServerでいうと「nvarchar」)です。
ちなみに子のレコードセット列のデータ型は「adChapter」となっています。

データ型はおそらく「ADODB.DataTypeEnum」にあるものだとは思うのですが、
どこかの記事で説明したとおりフォームに連結する場合は、
なぜか「adLongVarWChar」でなければいけません。エラーが出てしまいます。

「MSDataShape」プロバイダ、機会があったらぜひ使ってみましょう。

MSDataShape その2

サービスプロバイダを使う場合、接続文字列が少し異なってきます。
「MSDataShape」プロバイダはサービスプロバイダでデータ加工を担当しますが、
データ取得は普段指定しているプロバイダを利用します。
接続文字列としては
“Provider”→サービスプロバイダ
“Data Provider”→データプロバイダ
となります。

「C:\data.accdb」に接続する場合は以下のとおり。

    Dim cn As New ADODB.Connection
    cn.Open “Provider=MSDataShape;Data Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\data.accdb”

接続後「MSDataShape」を使って階層化レコードセットを作成するには

以下のような構文のShapeコマンドを発行します。
    Shape {} APPEND ({}
        RELATE TO ) as Childrst
この構文で親のRecordsetに「Childrst」という名前の列(Fieldオブジェクト)が追加され、
RELETEで指定したの値でにフィルターがかかった{子のSQL文}のRecordsetオブジェクトが列「Childrst」の値になります。

例)商品テーブル「tbl_商品」と分類テーブル「tbl_分類」がある場合

左図のようなテーブルとデータです。
よくある「分類」で「商品」を絞るときのテーブル
構成だと思います。

実際に「tbl_分類」と「tbl_商品」で階層化レコードセットを作成します。

Public Sub test()
    Dim ConnectionString As String
    ConnectionString = “Provider=MSDataShape;”
    ConnectionString = ConnectionString & “Data Provider=Microsoft.ACE.OLEDB.12.0;”
    ConnectionString = ConnectionString & “Data Source=C:\data.accdb;”
    Dim rst As New ADODB.Recordset
    Dim SQL As String
    SQL = “SHAPE {select 分類ID, 分類名 from tbl_分類} as p_rst “
    SQL = SQL & “APPEND ({select 分類ID, 商品ID, 商品名 from tbl_商品} as c_rst “
    SQL = SQL & “RELATE 分類ID TO 分類ID)”
    rst.Open SQL, ConnectionString
    With rst
        Do Until .EOF
        
            Debug.Print .Fields(“分類ID”).Value
            Debug.Print .Fields(“分類名”).Value
            Debug.Print .Fields(“c_rst”).Value.GetString
            
            .MoveNext
        Loop
    End With

End Sub

test
 1 
テスト
1   1   あ
1   2   い
1   5   お
 2 
テスト1
2   3   う
2   4   え
最も注目すべきなのはデータを表示する部分の
Debug.Print .Fields(“c_rst”).Value.GetString
この部分です。

「select 分類ID, 分類名 from tbl_分類」では「分類ID」と「分類名」の列だけになりますが、
「APPEND ({select 分類ID, 商品ID, 商品名 from tbl_商品} as c_rst 」により
「c_rst」の列が追加され「rst.Fields(“c_rst”).Value」で参照出来ることがわかります。

なぜGetStringメソッドで値を取得できるかというと
「rst.Fields(“c_rst”).Value」はRecordsetオブジェクトだからです。

その内容は「select 分類ID, 商品ID, 商品名 from tbl_商品」の子Recordsetの「分類ID」に対して
親Recordsetの「分類ID」の値でフィルターをかけたものになります。

MSDataShape その1

今回はほとんど陽の目を浴びないサービスプロバイダ
「MSDataShape(正式名称:Microsoft Data Shaping Service for OLE DB)」について。

参考URL:http://msdn.microsoft.com/ja-jp/library/cc426812.aspx
                http://msdn.microsoft.com/ja-jp/library/cc426820.aspx

サービスプロバイダとは?
「データの作成と利用の処理をカプセル化して、ADO アプリケーションの機能を強化します。」
言葉通りの意味で一風変わったRecordsetオブジェクトが作れます。

前のADOの記事でも書いたこのコード

Dim strm as ADODB.Stream
Set strm = New ADODB.Stream
strm.Open
rst1.Save strm, adPersistADTG
Set rst2 = New ADODB.Recordset
rst2.ActiveConnection = “Provider=MSPersist”
rst2.Open strm
Recordsetを保存した際のコードですが、この時に指定したプロバイダもサービスプロバイダで
「MSPersist(正式名称:Microsoft OLE DB Persistence Provider)」です。
これはRecordsetオブジェクトをファイル保存し、データや保留中の変更を復元するプロバイダです。
これによって出来るRecordsetは普段のRecordsetとほとんど違わないためよくわかりませんでしたが
「MSDataShape」は階層Recordsetを構築するという点でかなり特徴的です。
階層RecordsetというのはAccessでいうと
「リレーションシップ等で見れるサブデータシート」が一番近いイメージだと思います。
一対多のリレーションシップを作成し、一側のテーブルを表示すると左端に「+」マークが出て
多側のテーブルを展開できます。
ShapeコマンドはこれをSQLで実行し、Recordsetを作成するためのサービスプロバイダです。

If分岐とメッセージボックス

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult Ret = MessageBox.Show(“終了します。よろしいですか?”, “Sliverlight終了”, MessageBoxButton.OKCancel);
            if (Ret == MessageBoxResult.OK)
            {
                Application.Current.MainWindow.Close();
            }
        }
メッセージボックスの結果によってウィンドウを閉じています。

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show(“終了します。よろしいですか?”, “Sliverlight終了”, MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                Application.Current.MainWindow.Close();
            }
        }
↑変数に結果を保持しない方法

C#でSilverlightのデスクトップアプリの作成開始

やっとやりたいことが始められそうです。
C#も使ってみたかったですし、Silverlightの「Out of Browser」を使った
デスクトップアプリケーションも見てみたかったのでもうどっちも最初から始めます。
「VB.Net」は飛ばします(笑)。

参考URL:http://d.hatena.ne.jp/k_maru/20091126/1259185715

        <Button Content="Click Me" HorizontalAlignment="Center"
            VerticalAlignment=”Center” Click=”Button_Click” />
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(“Silverlight開始”);
        }

とりあえずメッセージボックスの関数習得?表題は決められないのかな?
Out of Browser(今後oobとします)の設定はプロジェクトのプロパティ「Silverlight」タグの
「アプリケーションのブラウザー外実行を有効にする」にチェックします。

ウィンドウを半透明化

ウィンドウを半透明化するとちょっとかっこいいと感じる私だけ?
実際に作ってみるとAccessの上をいってる感が結構あると思いますよ。

Private Declare Function GetWindowLong Lib “user32” _
                Alias “GetWindowLongA” ( _
                ByVal Hwnd As Long, ByVal Idx As Long) As Long

Private Declare Function SetWindowLong Lib “user32” _
                Alias “SetWindowLongA” ( _
                ByVal Hwnd As Long, _
                ByVal Idx As Long, _
                ByVal Style As Long) As Long

Private Declare Function SetLayeredWindowAttributes Lib “user32” ( _
                ByVal Hwnd As Long, _
                ByVal crKey As Long, _
                ByVal bAlpha As Long, _
                ByVal dwFlags As Long) As Long

Private Const GWL_EXSTYLE = (-20)
Private Const WS_EX_TOOLWINDOW = &H80
Private Const WS_EX_LAYERED = &H80000
Private Const LWA_COLORKEY = 1
Private Const LWA_ALPHA = 2

Public Sub WindowTransParent(FormName As String, Optional Alpha As Long = 192)
    If CurrentProject.AllForms(FormName).IsLoaded = False Then DoCmd.OpenForm FormName
 
    SetWindowLong Forms(FormName).Hwnd, GWL_EXSTYLE, GetWindowLong(Forms(FormName).Hwnd, GWL_EXSTYLE) Or WS_EX_LAYERED
    SetLayeredWindowAttributes Forms(FormName).Hwnd, 0, Alpha, LWA_ALPHA
End Sub

私はこのようにモジュールのAPI関数は「Private」で記述してそれらを使った関数を「Public」にしています。
呼び出すときは最低限の引数でわかりやすく呼び出したいからです。

    WindowTransParent ,

これで指定したフォームが指定した透明度の値になります。

フォームのポップアップを忘れずに。
「境界線スタイル」→なし
「移動ボタン」→なし
「レコードセレクタ」→なし
「スクロールバー」→なし
で完全にフォームに見えません。

Accessでタッチパネルを意識したソフトを作る

Accessのソフトをタッチパネルディスプレイで使ってみると普通の画面でも
スクロールバーが触りにくかったりボタンが小さくて押しにくかったり色々と発見があります。

あまりタッチパネルの利点を生かしたAccessのソフトはないようです。
(そろそろAccessとかVBA終わりそうとかいうのは禁止です)
ここは敢えて「Access」でタッチパネルを意識したソフトを作るためにいろいろやってみた
のでそれを今後のブログのネタに混ぜていきます。

「やれば出来る」と思って、「なんでAccessで?」というのも無視で行きます。