MW211 EXIT

devlog
jQueryUI/タブを画面いっぱいに
2021年01月08日
タブ(Tabs)を画面いっぱいに表示する方法。
┌──────────────────────────────────────┐
│$(this).tabs({heightStyle:'fill'});                                         │
└──────────────────────────────────────┘
親要素に合わせてサイズが調整される。

分類:jQuery
MSSQL/PDOとOracleリンクサーバと論理型
2020年11月30日
┌──────────────────────────────────────┐
│$sql = <<<___SQL___                                                         │
│SELECT [論理] FROM OPENQUERY(ORACLE, 'SELECT 0 AS "論理" FROM DUAL') AS [o] │
│___SQL___;                                                                  │
│$sth = PDO->prepare($sql);                                                  │
│$sth->execute();                                                            │
│$row = $sth->fetch(PDO::FETCH_ASSOC);                                       │
│if (!$row['論理']) {                                                        │
│    // 偽:偽のつもりで0を返却しているのでこちらを期待するのだが            │
│} else {                                                                    │
│    // 真:こちらになってしまう                                             │
│}                                                                           │
└──────────────────────────────────────┘
論理型はOracleでもMSSQLでも、「0」と「1」を用いるのが普通だ。
ところが、上記のようにPDOを用いて、リンクサーバ経由で
Oracleから偽のつもりで「0」を取得したら、PHP上では真となってしまった。

原因は以下の通り。
(1) PHPで数値型の「0」や「0.0」、文字列型の「0」は、偽(FALSE)扱いなのだが
    文字列型の「0.0」は真(TRUE)扱いとなってしまう
(2) PDOで値を取得すると、(基本的に)文字列型となる
(3) OPENQUERY()でOracleから0を取得すると、float型の「0.0」となってしまう
    整数ではなく小数のnumber型がOracleでは基本のため

よって、(2)と(3)の組み合わせにより、(1)の条件に適合してしまったようだ。

ということで、MSSQLの世界ではbit型で論理型の代用をするので
SQL(MSSQL)上で以下のように変換してから、PDOで読み込むのがよいようだ。
┌──────────────────────────────────────┐
│SELECT CONVERT([bit], [論理]) AS [論理]~                                   │
└──────────────────────────────────────┘
分類:PDO、MSSQL
Python/変換処理
2020年11月18日
┌──────────────────────────────────────┐
│switch (入力) {                                                             │
│    case "a": 出力 = "A";  break;                                           │
│    case "b": 出力 = "B";  break;                                           │
│    case "c": 出力 = "C";  break;                                           │
│    default : 出力 = 入力; break;                                           │
│}                                                                           │
└──────────────────────────────────────┘
上記のような処理をPythonで記述する場合、以下のようなif文にならざろうえない。
┌──────────────────────────────────────┐
│if 入力 == "a":                                                             │
│    出力 = "A"                                                              │
│elif 入力 == "b":                                                           │
│    出力 = "B"                                                              │
│elif 入力 == "c":                                                           │
│    出力 = "C"                                                              │
│else:                                                                       │
│    出力 = 入力                                                             │
└──────────────────────────────────────┘
これをスマートに記述するには連想配列を駆使するのがよいようだ。
┌──────────────────────────────────────┐
│aryConv = {                                                                 │
│    "a" :"A",                                                               │
│    "b" :"B",                                                               │
│    "c" :"C"                                                                │
│}                                                                           │
│if 入力 in aryConv:                                                         │
│    出力 = aryConv[入力]                                                    │
│else:                                                                       │
│    出力 = 入力                                                             │
└──────────────────────────────────────┘

必ず該当するのであれば以下もあり。
┌──────────────────────────────────────┐
│出力 = {                                                                    │
│    "a" :"A",                                                               │
│    "b" :"B",                                                               │
│    "c" :"C"                                                                │
│}.get(入力, 入力)                                                           │
└──────────────────────────────────────┘
分類:Python
MSSQL/単純なCSV
2020年10月06日
一列をすべてCSVにする方法。
┌──────────────────────────────────────┐
│WITH [表] (                                                                 │
│         [列]                                                               │
│     ) AS (                                                                 │
│         SELECT [列]                                                        │
│             FROM (                                                         │
│                 VALUES ('A'),('B'),('C')                                   │
│             ) AS [表]([列])                                                │
│     )                                                                      │
│SELECT REPLACE((SELECT [表].[列] AS [data()]                                │
│                    FROM [表]                                               │
│                    FOR XML PATH ('')       ), ' ', ',') AS [列たち];       │
└──────────────────────────────────────┘
分類:MSSQL
PHP/RESTAPI的なことをしてみよう
2020年09月26日
jQuery側(JavaScript)の処理(抜粋)。
┌──┬───────────────────────────────────┐
│参照│$.ajax({                                                              │
│    │    url         :'http://xxxx/api',                                   │
│    │    type        :'GET',                                               │
│    │    data        :JSONデータ,                                          │
├──┼───────────────────────────────────┤
│追加│$.ajax({                                                              │
│    │    url         :'http://xxxx/api',                                   │
│    │    type        :'POST',                                              │
│    │    data        :JSONデータ,                                          │
├──┼───────────────────────────────────┤
│変更│$.ajax({                                                              │
│    │    url         :'http://xxxx/api',                                   │
│    │    type        :'PUT',                                               │
│    │    data        :JSONデータ,                                          │
├──┼───────────────────────────────────┤
│削除│$.ajax({                                                              │
│    │    url         :'http://xxxx/api',                                   │
│    │    type        :'DELETE',                                            │
│    │    data        :JSONデータ,                                          │
└──┴───────────────────────────────────┘

PHP側の処理例。
┌──────────────────────────────────────┐
│switch ($_SERVER['REQUEST_METHOD']) {                                       │
│    case 'GET':                                                             │
│        $data = $_GET;                                                      │
│        echo $this->select($data);                                          │
│        break                                                               │
│    case 'POST':                                                            │
│        $data = $_POST;                                                     │
│        $this->insert($data);                                               │
│        break                                                               │
│    case 'PUT':                                                             │
│        parse_str(urldecode(file_get_contents('php://input')), $data);      │
│        $this->update($data);                                               │
│        break                                                               │
│    case 'DELETE':                                                          │
│        parse_str(urldecode(file_get_contents('php://input')), $data);      │
│        $this->delete($data);                                               │
│        break                                                               │
│}                                                                           │
└──────────────────────────────────────┘
PUTメソッドとDELETEメソッドについては専用のシステム定数がないので
「php://input」からひっぱてくる形となる。
分類:PHP
MSSQL/MERGE INTOで差分がある時だけ更新
2020年09月25日
USINGの前にNOT EXISTSで同一データを除外。
(後で除外するとNOT MATHCED扱いとなるので注意)
同一判定をする時にはNULLに注意(NULLのままでは不一致になるので空文字に置換)。
┌──────────────────────────────────────┐
│MERGE INTO [出力D]                                                         │
│    USING (                                                                 │
│        SELECT [キー],                                                      │
│               [データ],                                                    │
│               GETDATE() AS [更新日時]                                      │
│            FROM [入力D]                                                   │
│            WHERE NOT EXISTS (                                              │
│SELECT *                                                                    │
│    FROM [出力D]                                                           │
│    WHERE ISNULL([出力D].[キー]  , '') = ISNULL([入力D].[キー]  , '')     │
│      AND ISNULL([出力D].[データ], '') = ISNULL([入力D].[データ], '')     │
│                  )                                                         │
│    ) AS [入力D]                                                           │
│      ON  [入力D].[キー] = [出力D].[キー]                                 │
│    WHEN MATCHED THEN                                                       │
│        UPDATE SET [データ]   = [入力D].[データ],                          │
│                   [更新日時] = [入力D].[更新日時]                         │
│    WHEN NOT MATCHED BY TARGET THEN                                         │
│        INSERT (                                                            │
│                [キー],                                                     │
│                [データ],                                                   │
│                [更新日時]                                                  │
│            ) VALUES (                                                      │
│                [入力D].[キー],                                            │
│                [入力D].[データ],                                          │
│                [入力D].[更新日時]                                         │
│            );"                                                             │
└──────────────────────────────────────┘
こうすると、更新日時の変更を差分があった時に限定できる。
分類:MSSQL
ExceVBA/プレースホルダの型指定
2020年09月18日
ExceVBAにおけるプレースホルダ(ADODB.Command.CreateParameter)のデータ型は
以下の通り。
┌───────┬──┬─┬────┐
│プレースホルダ│ 値 │幅│MSSQL型 │
├───────┼──┼─┼────┤
│adBoolean     │  11│-│bit     │
│adInteger     │   3│-│int     │
├───────┼──┼─┼────┤
│adChar        │ 129│○│char    │
│adWChar       │ 130│○│nchar   │
│adVarChar     │ 200│○│varchar │
│adVarWChar    │ 202│○│nvarchar│
├───────┼──┼─┼────┤
│adDate        │   7│-│date    │
│adDBTimeStamp │ 135│-│datetime│
└───────┴──┴─┴────┘
分類:ExcelVBA
ExcelVBA/フォーム入力欄チェックの落とし穴(3)
2020年09月12日
さて、(1)~(2)で対応完了だが、なんとなく関係なページでも発動するのが嫌だ。
ってことで特定のページのみに限定する方法。

まず、Exitイベントだがこれは簡単で、Exit前のページ番号が取得できるので
それを参照すればよい。
(なお、ページ番号は値としては0オリジンで管理されているので注意)
┌──────────────────────────────────────┐
│Private Sub MultiPage_Exit(ByVal Cancel As MSForms.ReturnBoolean)           │
│    If Me.MultiPage.Value = 2 Then ' 3ページのみ限定                        │
│        ' 入力チェックや補正                                                │
│    End If                                                                  │
│End Sub                                                                     │
└──────────────────────────────────────┘

次に、ChangeイベントだがこれはChange後のページ番号になってしまうので厄介だ。
Static変数に一つ前の値を記録しておくのがよいようだ。
いっそのこと、メンバ変数(Static変数も兼ねる)にしてしまった方が
わかりやすいということで以下のような感じになる。
┌──────────────────────────────────────┐
│Private m前ページ As Long                                                   │
├──────────────────────────────────────┤
│Private Sub UserForm_Initialize()                                           │
│    m前ページ = Me.MultiPage.Value                                          │
│End Sub                                                                     │
├──────────────────────────────────────┤
│Private Sub MultiPage_Change()                                              │
│    If m前ページ = 2 Then       ' 3ページのみ限定                           │
│        ' 入力チェックや補正                                                │
│        ' 入力チェックや補正                                                │
│        ' 入力チェックや補正                                                │
│    End If                                                                  │
│    m前ページ = Me.MultiPage.Value                                          │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/フォーム入力欄チェックの落とし穴(2)
2020年09月11日
マルチページの場合、他のページに直接飛んだ場合にも
Exitイベントが効かないようようだ。
┌──────────────────────────────────────┐
│Private Sub TextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)             │
│    ' 入力チェックや補正                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘

となると、いよいよページの変更イベントに仕込む必要も出てくる。
┌──────────────────────────────────────┐
│Private Sub MultiPage_Change()                                              │
│    ' 入力チェックや補正                                                    │
│    ' 入力チェックや補正                                                    │
│    ' 入力チェックや補正                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘
しかも、どの入力欄からなのかが定まらないのですべてに対応って感じになるのか?

そうなるとチェック処理を関数化したくなってくる。
引数に入力欄を渡す方法は以下のような感じになる。
┌──────────────────────────────────────┐
│Call 入力チェック(Me.TextBox)                                               │
├──────────────────────────────────────┤
│Private Sub 入力チェック(ByVal テキストボックス As MSForms.TextBox)         │
│    ' 入力チェックや補正                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/フォーム入力欄チェックの落とし穴(1)
2020年09月10日
フォームの入力欄にて入力直後に入力チェックや補正を行う処理を実装するには
Exitイベント(フォーカスアウト)に仕込めばよい、通常は。
┌──────────────────────────────────────┐
│Private Sub TextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)             │
│    ' 入力チェックや補正                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘

とこらが、マルチページ環境のページ(タブ)の中の最後の入力欄だった場合には
ページを離脱することになり、上記イベントが効かなくなる。
(同一ページ内の他のコントロールにフォーカスがあたらないからという解釈だろうか)

ま、画面設計を巧妙にいじって、その入力欄が最後にならないように配置するというのが
回避策として無難なところだが、他者からの依頼の場合など
そうもいっていられないことがある。

ということで、水面下で回避する方法。
┌──────────────────────────────────────┐
│Private Sub MultiPage_Exit(ByVal Cancel As MSForms.ReturnBoolean)           │
│    ' 入力チェックや補正                                                    │
│End Sub                                                                     │
└──────────────────────────────────────┘
なんのことはないページ離脱時に処理を移動すればいいのだ。(ちと微妙だが)
分類:ExcelVBA
前へ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 … 156 次へ