MW211 EXIT

devlog
ExcelVBA/あいまい判定
2014年11月26日
通常の判定は以下の通り。
┌──────────────────────────────────────┐
│If 変数 = "キーワード" Then                                                 │
│    MsgBox "該当あり"                                                       │
│End If                                                                      │
└──────────────────────────────────────┘

これをあいまい判定する場合には「Like」を使う。
┌──────────────────────────────────────┐
│If 変数 Like "*キーワード*" Then                                            │
│    MsgBox "該当あり"                                                       │
│End If                                                                      │
└──────────────────────────────────────┘
SQLのLike判定ライクだ。
分類:ExcelVBA
MSSQL/一意制約の後付け時に
2014年11月25日
┌──────────────────────────────────────┐
│CREATE UNIQUE NONCLUSTERED INDEX [一意制約] ON [データベース].[dbo].[表] (  │
│    [列]            ASC                                                     │
│);                                                                          │
└──────────────────────────────────────┘
一意制約を後から付けた場合に、既に重複していたらどうなるか?
┌──────────────────────────────────────┐
│オブジェクト名 'dbo.表' およびインデックス名 '一意制約' に                  │
│重複したキーが見つかったので、                                              │
│CREATE UNIQUE INDEX ステートメントは終了しました。                          │
│重複したキーの値は (■) です。                                              │
│ステートメントは終了されました。                                            │
└──────────────────────────────────────┘
一意制約を付けられないというのが正解です。
分類:MSSQL
MSSQL/更新直後トリガで表を参照した場合
2014年11月24日
「AFTER UPDATE」の時に、「inserted」ではなく表を参照した場合、
参照が反映されているかをふと気になったので確認してみた。
  →結論:反映されている

【前準備】
┌──────────────────────────────────────┐
│CREATE DATABASE [実験DB];                                                   │
├──────────────────────────────────────┤
│CREATE TABLE [実験DB].[dbo].[T_実験] (                                      │
│    [キー]              [int]               NOT NULL,                       │
│    [値1]               [int]               NULL,                           │
│    [値2]               [int]               NULL,                           │
│    CONSTRAINT [PK_実験] PRIMARY KEY CLUSTERED (                            │
│        [キー]                ASC                                           │
│    )                                                                       │
│);                                                                          │
├──────────────────────────────────────┤
│CREATE VIEW [dbo].[V_実験]                                                  │
│AS                                                                          │
│    SELECT [キー],                                                          │
│           [値1],                                                           │
│           [値2]                                                            │
│        FROM [実験DB].[dbo].[T_実験]                                        │
│;                                                                           │
└──────────────────────────────────────┘

【トリガ1】
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[TRIGGER_実験] ON [実験DB].[dbo].[T_実験]              │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    BEGIN                                                                   │
│        UPDATE [実験DB].[dbo].[T_実験]                                      │
│            SET [値2] = inserted.[値1]                                      │
│            FROM inserted                                                   │
│            WHERE [T_実験].[キー] = inserted.[キー]                         │
│    END;                                                                    │
│END;                                                                        │
└──────────────────────────────────────┘
  直にinsertedを見るパターン。
  「値1」の値を変更すると「値2」に反映される。(想定通り)

【トリガ2】
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[TRIGGER_実験] ON [実験DB].[dbo].[T_実験]              │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    BEGIN                                                                   │
│        UPDATE [実験DB].[dbo].[T_実験]                                      │
│            SET [値2] = [新].[値1]                                          │
│            FROM inserted                                                   │
│                INNER JOIN [実験DB].[dbo].[T_実験] AS [新]                  │
│                  ON [新].[キー] = inserted.[キー]                          │
│    END;                                                                    │
│END;                                                                        │
└──────────────────────────────────────┘
  表を参照するパターン。
  「値1」の値を変更すると「値2」に反映される。(これも想定通り)

【トリガ3】
-- DROP TRIGGER [dbo].[TRIGGER_実験];
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[TRIGGER_実験] ON [実験DB].[dbo].[T_実験]              │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    BEGIN                                                                   │
│        UPDATE [実験DB].[dbo].[T_実験]                                      │
│            SET [値2] = [新].[値1]                                          │
│            FROM inserted                                                   │
│                INNER JOIN [実験DB].[dbo].[V_実験] AS [新]                  │
│                  ON [新].[キー] = inserted.[キー]                          │
│    END;                                                                    │
│END;                                                                        │
└──────────────────────────────────────┘
  仮想表を介して表を参照するパターン。
  「値1」の値を変更すると「値2」に反映される。(これも想定通り)

もし、「値1」が昔の値のままなら、「値2」も昔の値に更新される
…が、そうはならないことを確認。
分類:MSSQL
ExcelVBA/INIファイルの読み書き
2014年11月23日
クラス化すると以下のような感じ。
┌──────────────────────────────────────┐
│ClassINI.cls                                                                │
├──────────────────────────────────────┤
│Option Explicit                                                             │
│'***************************************************************************│
│'  クラス:INIファイル                                                      │
│'***************************************************************************│
│Private mINIファイル As String                                              │
│Private m環境名 As String                                                   │
│'===========================================================================│
│'  宣言:INIファイルアクセス関数(API)                                       │
│'===========================================================================│
│Private Declare Function GetPrivateProfileString Lib "kernel32" _           │
│    Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, _  │
│                                      ByVal lpKeyName As Any, _             │
│                                      ByVal lpDefault As String, _          │
│                                      ByVal lpReturnedString As String, _   │
│                                      ByVal nSize As Long, _                │
│                                      ByVal lpFileName As String) As Long   │
│Private Declare Function WritePrivateProfileString Lib "kernel32" _         │
│    Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, _│
│                                        ByVal lpKeyName As Any, _           │
│                                        ByVal lpString As Any, _            │
│                                        ByVal lpFileName As String) As Long │
│'===========================================================================│
│'  コンストラクタ                                                           │
│'===========================================================================│
│Private Sub Class_Initialize()                                              │
│End Sub                                                                     │
│'===========================================================================│
│'  メソッド:準コンストラクタ                                               │
│'===========================================================================│
│Public Sub 準コンストラクタ(ByVal INIファイル As String)                    │
│    If InStr(INIファイル, "\") = 0 Then                                     │
│        mINIファイル = Application.ThisWorkbook.Path & "\" & INIファイル    │
│    Else                                                                    │
│        mINIファイル = INIファイル                                          │
│    End If                                                                  │
│End Sub                                                                     │
│'===========================================================================│
│'  デストラクタ                                                             │
│'===========================================================================│
│Private Sub Class_Terminate()                                               │
│End Sub                                                                     │
│'===========================================================================│
│'  メソッド:参照                                                           │
│'===========================================================================│
│Public Function getter(ByVal セクション As String, _                        │
│                       ByVal キー As String, _                              │
│                       ByVal 既定値 As String) As String                    │
│    Dim ファイル名 As String                                                │
│    Dim リターンコード As Long                                              │
│    Dim 取得値 As String                                                    │
│    取得値 = Space$(256)                                                    │
│    リターンコード = GetPrivateProfileString(セクション, _                  │
│                                             キー, _                        │
│                                             既定値, _                      │
│                                             取得値, _                      │
│                                             255, _                         │
│                                             mINIファイル)                  │
│    If リターンコード > 0 Then                                              │
│        If InStr(取得値, Chr$(0)) > 0 Then                                  │
│            getter = Left$(取得値, InStr(取得値, Chr$(0)) - 1)              │
│        Else                                                                │
│            getter = ""                                                     │
│        End If                                                              │
│    Else                                                                    │
│        getter = 既定値                                                     │
│    End If                                                                  │
│End Function                                                                │
│'===========================================================================│
│'  メソッド:設定                                                           │
│'===========================================================================│
│Public Function setter(ByVal セクション As String, _                        │
│                       ByVal キー As String, _                              │
│                       ByVal 設定値 As String) As Long                      │
│    Dim ファイル名 As String                                                │
│    Dim リターンコード As Long                                              │
│    リターンコード = WritePrivateProfileString(セクション, _                │
│                                               キー, _                      │
│                                               設定値, _                    │
│                                               mINIファイル)                │
│    setter = リターンコード                                                 │
│End Function                                                                │
│'***************************************************************************│
└──────────────────────────────────────┘
以下のような感じで実行できる
┌──────────────────────────────────────┐
│Option Explicit                                                             │
│Public Sub 実行()                                                           │
│    Dim objINI As New ClassINI                                              │
│    Call objINI.準コンストラクタ("環境設定.ini")                            │
│    MsgBox objINI.getter("DB", "SERVER_NAME", "既定値")                     │
│    Call objINI.setter("DB", "SERVER_NAME", "設定値")                       │
│End Sub                                                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/Variant型の比較
2014年11月16日
Variant型に値を代入等して比較等した結果。
┌──┬─────┬─────┬─────┬─────┬─────┬─────┐
│値\│= 0       │= 1       │= ""      │= "a"     │IsEmpty() │= Empty   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│未入│   ○真   │   ×偽   │   ○真   │   ×偽   │   ○真   │   ○真   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│   0│   ○真   │   ×偽   │   ×偽   │   ×偽   │   ×偽   │   ○真   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│   1│   ×偽   │   ○真   │   ×偽   │   ×偽   │   ×偽   │   ×偽   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│""  │   ×偽   │   ×偽   │   ○真   │   ×偽   │   ×偽   │   ○真   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│"a" │   ×偽   │   ×偽   │   ×偽   │   ○真   │   ×偽   │   ×偽   │
├──┼─────┼─────┼─────┼─────┼─────┼─────┤
│Null│   ×偽   │   ×偽   │   ×偽   │   ×偽   │   ×偽   │   ×偽   │
└──┴─────┴─────┴─────┴─────┴─────┴─────┘
┌──┬─────┬───────────┬─────┐
│値\│IsNull()  │= vbNullString        │Is Nothing│
├──┼─────┼───────────┼─────┤
│未入│   ×偽   │         ○真         │ (エラー) │
├──┼─────┼───────────┼─────┤
│   0│   ×偽   │         ×偽         │ (エラー) │
├──┼─────┼───────────┼─────┤
│   1│   ×偽   │         ×偽         │ (エラー) │
├──┼─────┼───────────┼─────┤
│""  │   ×偽   │         ○真         │ (エラー) │
├──┼─────┼───────────┼─────┤
│"a" │   ×偽   │         ×偽         │ (エラー) │
├──┼─────┼───────────┼─────┤
│Null│   ○真   │         ×偽         │ (エラー) │
└──┴─────┴───────────┴─────┘
┌──┬─────┬───────────┐
│値\│  Len()   │      VarType()       │
├──┼─────┼───────────┤
│未入│     0    │     0(vbEmpty)       │
├──┼─────┼───────────┤
│   0│     1    │     2(vbInteger)     │
├──┼─────┼───────────┤
│   1│     1    │     2(vbInteger)     │
├──┼─────┼───────────┤
│""  │     0    │     8(vbString)      │
├──┼─────┼───────────┤
│"a" │     1    │     8(vbString)      │
├──┼─────┼───────────┤
│Null│   Null   │     1(vbNull)        │
└──┴─────┴───────────┘
分類:ExcelVBA
SQL/順番再計算
2014年11月14日
親キーごとに基準項目を元に、連番を昇順に振り直す場合は、以下の通り。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 順番項目 = (                                                        │
│        SELECT COUNT(*)                                                     │
│            FROM 表 AS 順番調査                                             │
│            WHERE 順番調査.親キー   =  表.親キー                            │
│              AND 順番調査.基準項目 <= 表.基準項目                          │
│    );                                                                      │
└──────────────────────────────────────┘

但し、基準項目がグループ内で一意でなければ、同順位が発生してしまうので
便宜上、一意キー(主キーなど)で、以下のように重複を分散させる場合あり。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 順番項目 = (                                                        │
│        SELECT COUNT(*)                                                     │
│            FROM 表 AS 順番調査                                             │
│            WHERE 順番調査.親キー = 表.親キー                               │
│              AND (順番調査.基準項目 < 表.基準項目                          │
│               OR  (順番調査.基準項目 =  表.基準項目                        │
│                AND 順番調査.一意キー <= 表.一意キー))                      │
│    );                                                                      │
└──────────────────────────────────────┘
分類:SQL
ExcelVBA/IsEmpty関数の罠
2014年11月10日
「IsEmpty()」は「0」や「""」(長さ0の文字列)を比較する関数ではなく
未初期化(定義後一度も代入していない)を判定する関数なのだ。
┌──────────────────────────────────────┐
│Dim 変数 As Variant                                                         │
│MsgBox IsEmpty(変数) ' →True                                               │
│変数 = 0                                                                    │
│MsgBox IsEmpty(変数) ' →False                                              │
└──────────────────────────────────────┘
分類:注意、ExcelVBA
SQL/完全外部結合でNULL比較
2014年11月08日
「FULL JOIN」で完全外部結合し、NULLも含めた比較をしたい場合。
「NULL = NULL」では「真」にならないという障壁がある。

つまり、以下のような感じになり、「ギ」の部分が「真」でないという誤算がある。

【一致比較の場合】    【不一致比較の場合】
┌─┬─┬─┬─┐    ┌─┬─┬─┬─┐
│  │a│b│ヌ│    │  │a│b│ヌ│
├─┼─┼─┼─┤    ├─┼─┼─┼─┤
│a│真│偽│偽│    │a│偽│真│ギ│
├─┼─┼─┼─┤    ├─┼─┼─┼─┤
│b│偽│真│偽│    │b│真│偽│ギ│
├─┼─┼─┼─┤    ├─┼─┼─┼─┤
│ヌ│偽│偽│ギ│    │ヌ│ギ│ギ│偽│
└─┴─┴─┴─┘    └─┴─┴─┴─┘

ということで、「ギ」を「真」にするSQL文は以下のようになる。

【一致比較の場合】
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM [表1]                                                              │
│        FULL JOIN [表2]                                                     │
│          ON [表1].[キー] = [表2].[キー]                                    │
│    WHERE [表1].[列] = [表2].[列]                                           │
│       OR (([表1].[列] IS NULL) AND ([表2].[列] IS NULL));                  │
└──────────────────────────────────────┘

【不一致比較の場合】
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM [表1]                                                              │
│        FULL JOIN [表2]                                                     │
│          ON [表1].[キー] = [表2].[キー]                                    │
│    WHERE [表1].[列] <> [表2].[列]                                          │
│       OR (([表1].[列] IS     NULL) AND ([表2].[列] IS NOT NULL))           │
│       OR (([表1].[列] IS NOT NULL) AND ([表2].[列] IS     NULL));          │
└──────────────────────────────────────┘

もっと簡単な方法がありそうな気もするが、原始的な方法であれば上記の通りとなる。
分類:SQL
MSSQL/特定の列が更新されたか
2014年11月07日
トリガにて、特定の列が更新された場合に発動するように判定するには
「UPDATE()」を使う。
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[トリガ] ON [データベース].[dbo].[テーブル]            │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    IF UPDATE([列])                                                         │
│    BEGIN                                                                   │
│        SQL文;                                                              │
│    END;                                                                    │
│END;                                                                        │
└──────────────────────────────────────┘
但し、これは、その列がUPDATE文の対象だった場合に漏れなく発動し
内容に変化があったか否かは気にしない(同じ値で更新しても発動する)。

ということで、内容が変更された場合に限定するのは以下のような感じとなる。
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[トリガ] ON [データベース].[dbo].[テーブル]            │
│    AFTER UPDATE                                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    IF (SELECT [列] FROM inserted) <> (SELECT [列] FROM deleted)            │
│    BEGIN                                                                   │
│        SQL文;                                                              │
│    END;                                                                    │
│END;                                                                        │
└──────────────────────────────────────┘
分類:MSSQL
アクセス用語集
2014年11月06日
┌──────────────┬─────┬─────────────────┐
│一般的な大分類              │参照      │更新                              │
│                            │読込      │書込                              │
├──────────────┼─────┼─────┬─────┬─────┤
│ファイルアクセスの分類      │読込      │書込      │上書      │削除      │
│                            │READ      │WRITE     │REWRITE   │DELETE    │
├──────────────┼─────┼─────┼─────┼─────┤
│DBアクセス(SQL文)の分類     │          │追加      │変更      │削除      │
│                            │          │挿入      │更新      │削除      │
│                            │READ      │WRITE     │REWRITE   │DELETE    │
│                            │SELECT    │INSERT    │UPDATE    │DELETE    │
│                            ├─────┼─────┴─────┼─────┤
│                            │          │併合                  │削除      │
│                            │SELECT    │MERGE                 │DELETE    │
│                            │SELECT    │UPSERT                │DELETE    │
└──────────────┴─────┴───────────┴─────┘
分類:設計
前へ 1 … 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 … 156 次へ